@lemoncat7/dsh-theme-xiaohei 0.4.6 → 0.5.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 (232) hide show
  1. package/README.md +15 -9
  2. package/THIRD_PARTY_NOTICES.md +13 -1
  3. package/docs/dsh-021-compatibility.md +23 -0
  4. package/docs/releases/0.5.0.md +24 -0
  5. package/docs/rift-interaction.md +35 -0
  6. package/docs/rift-preview.md +39 -0
  7. package/lib/client.companion.js +3 -4
  8. package/lib/client.decorations.js +224 -51
  9. package/lib/client.js +532 -2405
  10. package/lib/index.d.ts +1 -2
  11. package/lib/index.js +393 -11
  12. package/lib/rift/boot.d.ts +6 -0
  13. package/package.json +29 -19
  14. package/lib/appearance.d.ts +0 -12
  15. package/lib/appearance.js +0 -42
  16. package/lib/blink.d.ts +0 -4
  17. package/lib/blink.js +0 -110
  18. package/lib/bloub-heixiu/ambient.d.ts +0 -3
  19. package/lib/bloub-heixiu/ambient.js +0 -12
  20. package/lib/bloub-heixiu/character.d.ts +0 -33
  21. package/lib/bloub-heixiu/character.js +0 -124
  22. package/lib/bloub-heixiu/effects.d.ts +0 -4
  23. package/lib/bloub-heixiu/effects.js +0 -91
  24. package/lib/bloub-heixiu/flight.d.ts +0 -15
  25. package/lib/bloub-heixiu/flight.js +0 -66
  26. package/lib/bloub-heixiu/follow.d.ts +0 -13
  27. package/lib/bloub-heixiu/follow.js +0 -23
  28. package/lib/bloub-heixiu/layout.d.ts +0 -34
  29. package/lib/bloub-heixiu/layout.js +0 -26
  30. package/lib/bloub-heixiu/renderer.d.ts +0 -16
  31. package/lib/bloub-heixiu/renderer.js +0 -94
  32. package/lib/bloub-heixiu/runtime.d.ts +0 -6
  33. package/lib/bloub-heixiu/runtime.js +0 -440
  34. package/lib/bloub-heixiu/signals.d.ts +0 -17
  35. package/lib/bloub-heixiu/signals.js +0 -55
  36. package/lib/bloub-heixiu/styles.d.ts +0 -2
  37. package/lib/bloub-heixiu/styles.js +0 -98
  38. package/lib/boot-appearance.d.ts +0 -10
  39. package/lib/boot-appearance.js +0 -47
  40. package/lib/boot-loader.d.ts +0 -5
  41. package/lib/boot-loader.js +0 -158
  42. package/lib/chrome/accessibility.d.ts +0 -3
  43. package/lib/chrome/accessibility.js +0 -69
  44. package/lib/chrome/blink.d.ts +0 -3
  45. package/lib/chrome/blink.js +0 -15
  46. package/lib/chrome/composer-avatar.d.ts +0 -10
  47. package/lib/chrome/composer-avatar.js +0 -599
  48. package/lib/chrome/composer-send-heixiu.d.ts +0 -3
  49. package/lib/chrome/composer-send-heixiu.js +0 -143
  50. package/lib/chrome/composer.d.ts +0 -3
  51. package/lib/chrome/composer.js +0 -135
  52. package/lib/chrome/controls.d.ts +0 -8
  53. package/lib/chrome/controls.js +0 -348
  54. package/lib/chrome/conversation-messages.d.ts +0 -3
  55. package/lib/chrome/conversation-messages.js +0 -329
  56. package/lib/chrome/conversation-submissions.d.ts +0 -3
  57. package/lib/chrome/conversation-submissions.js +0 -68
  58. package/lib/chrome/conversation.d.ts +0 -3
  59. package/lib/chrome/conversation.js +0 -67
  60. package/lib/chrome/frames.d.ts +0 -6
  61. package/lib/chrome/frames.js +0 -134
  62. package/lib/chrome/gaze.d.ts +0 -3
  63. package/lib/chrome/gaze.js +0 -103
  64. package/lib/chrome/identity.d.ts +0 -6
  65. package/lib/chrome/identity.js +0 -47
  66. package/lib/chrome/overlays.d.ts +0 -3
  67. package/lib/chrome/overlays.js +0 -104
  68. package/lib/chrome/portal.d.ts +0 -6
  69. package/lib/chrome/portal.js +0 -169
  70. package/lib/chrome/reactions.d.ts +0 -3
  71. package/lib/chrome/reactions.js +0 -85
  72. package/lib/chrome/sidebar.d.ts +0 -3
  73. package/lib/chrome/sidebar.js +0 -313
  74. package/lib/chrome/tokens.d.ts +0 -3
  75. package/lib/chrome/tokens.js +0 -224
  76. package/lib/chrome/workspace.d.ts +0 -3
  77. package/lib/chrome/workspace.js +0 -94
  78. package/lib/chrome.d.ts +0 -10
  79. package/lib/chrome.js +0 -46
  80. package/lib/client-entry.d.ts +0 -3
  81. package/lib/client-entry.js +0 -3
  82. package/lib/client.d.ts +0 -10
  83. package/lib/client.pose-chin-dark.js +0 -4
  84. package/lib/client.pose-chin-light.js +0 -4
  85. package/lib/client.pose-doze-dark.js +0 -4
  86. package/lib/client.pose-doze-light.js +0 -4
  87. package/lib/client.pose-halfpeek-dark.js +0 -4
  88. package/lib/client.pose-halfpeek-light.js +0 -4
  89. package/lib/client.pose-peek-dark.js +0 -4
  90. package/lib/client.pose-peek-light.js +0 -4
  91. package/lib/client.pose-seated-dark.js +0 -4
  92. package/lib/client.pose-seated-light.js +0 -4
  93. package/lib/client.rig-chin-dark.js +0 -4
  94. package/lib/client.rig-chin-light.js +0 -4
  95. package/lib/client.rig-halfpeek-dark.js +0 -4
  96. package/lib/client.rig-halfpeek-light.js +0 -4
  97. package/lib/client.rig-peek-dark.js +0 -4
  98. package/lib/client.rig-peek-light.js +0 -4
  99. package/lib/client.rig-seated-dark.js +0 -4
  100. package/lib/client.rig-seated-light.js +0 -4
  101. package/lib/companion-entry.d.ts +0 -3
  102. package/lib/companion-entry.js +0 -3
  103. package/lib/composer-avatar.d.ts +0 -18
  104. package/lib/composer-avatar.js +0 -441
  105. package/lib/composer-draft-preview.d.ts +0 -4
  106. package/lib/composer-draft-preview.js +0 -8
  107. package/lib/composer-send-heixiu.d.ts +0 -8
  108. package/lib/composer-send-heixiu.js +0 -133
  109. package/lib/current-session.d.ts +0 -6
  110. package/lib/current-session.js +0 -5
  111. package/lib/decorations-entry.d.ts +0 -3
  112. package/lib/decorations-entry.js +0 -18
  113. package/lib/deferred-companion.d.ts +0 -5
  114. package/lib/deferred-companion.js +0 -9
  115. package/lib/deferred-decorations.d.ts +0 -3
  116. package/lib/deferred-decorations.js +0 -51
  117. package/lib/gaze.d.ts +0 -4
  118. package/lib/gaze.js +0 -230
  119. package/lib/generated-backgrounds.d.ts +0 -14
  120. package/lib/generated-backgrounds.js +0 -14
  121. package/lib/generated-character-motion.d.ts +0 -4
  122. package/lib/generated-character-motion.js +0 -2
  123. package/lib/generated-identity.d.ts +0 -6
  124. package/lib/generated-identity.js +0 -6
  125. package/lib/generated-keyart.d.ts +0 -34
  126. package/lib/generated-keyart.js +0 -34
  127. package/lib/generated-loading-assets.d.ts +0 -4
  128. package/lib/generated-loading-assets.js +0 -4
  129. package/lib/heixiu-interactions.d.ts +0 -10
  130. package/lib/heixiu-interactions.js +0 -161
  131. package/lib/host-contract.d.ts +0 -9
  132. package/lib/host-contract.js +0 -13
  133. package/lib/host-dom.d.ts +0 -11
  134. package/lib/host-dom.js +0 -72
  135. package/lib/loading-heixiu.d.ts +0 -8
  136. package/lib/loading-heixiu.js +0 -287
  137. package/lib/metallic-brand-mark.d.ts +0 -10
  138. package/lib/metallic-brand-mark.js +0 -296
  139. package/lib/plugin.d.ts +0 -6
  140. package/lib/plugin.js +0 -60
  141. package/lib/portal.d.ts +0 -40
  142. package/lib/portal.js +0 -225
  143. package/lib/reactions.d.ts +0 -20
  144. package/lib/reactions.js +0 -380
  145. package/lib/scene/avatar-model.d.ts +0 -6
  146. package/lib/scene/avatar-model.js +0 -646
  147. package/lib/scene/avatar-motion.d.ts +0 -3
  148. package/lib/scene/avatar-motion.js +0 -799
  149. package/lib/scene/character-assets.d.ts +0 -13
  150. package/lib/scene/character-assets.js +0 -26
  151. package/lib/scene/character-expression.d.ts +0 -4
  152. package/lib/scene/character-expression.js +0 -15
  153. package/lib/scene/character-eye-material.d.ts +0 -13
  154. package/lib/scene/character-eye-material.js +0 -88
  155. package/lib/scene/character-eye-renderer.d.ts +0 -5
  156. package/lib/scene/character-eye-renderer.js +0 -80
  157. package/lib/scene/character-eye-rig.d.ts +0 -20
  158. package/lib/scene/character-eye-rig.js +0 -35
  159. package/lib/scene/character-gaze.d.ts +0 -16
  160. package/lib/scene/character-gaze.js +0 -36
  161. package/lib/scene/character-idle.d.ts +0 -17
  162. package/lib/scene/character-idle.js +0 -65
  163. package/lib/scene/character-layout.d.ts +0 -24
  164. package/lib/scene/character-layout.js +0 -51
  165. package/lib/scene/character-motion-clock.d.ts +0 -18
  166. package/lib/scene/character-motion-clock.js +0 -70
  167. package/lib/scene/character-motion-types.d.ts +0 -12
  168. package/lib/scene/character-motion-types.js +0 -2
  169. package/lib/scene/character-motion.d.ts +0 -6
  170. package/lib/scene/character-motion.js +0 -187
  171. package/lib/scene/character-poses.d.ts +0 -26
  172. package/lib/scene/character-poses.js +0 -11
  173. package/lib/scene/character-rig-renderer.d.ts +0 -5
  174. package/lib/scene/character-rig-renderer.js +0 -95
  175. package/lib/scene/character-rig.d.ts +0 -22
  176. package/lib/scene/character-rig.js +0 -61
  177. package/lib/scene/heixiu-feedback.d.ts +0 -3
  178. package/lib/scene/heixiu-feedback.js +0 -64
  179. package/lib/scene/heixiu-interactions.d.ts +0 -3
  180. package/lib/scene/heixiu-interactions.js +0 -92
  181. package/lib/scene/ids.d.ts +0 -5
  182. package/lib/scene/ids.js +0 -5
  183. package/lib/scene/pointer-bridge.d.ts +0 -21
  184. package/lib/scene/pointer-bridge.js +0 -155
  185. package/lib/scene/runtime.d.ts +0 -12
  186. package/lib/scene/runtime.js +0 -74
  187. package/lib/scene/state-transitions.d.ts +0 -3
  188. package/lib/scene/state-transitions.js +0 -37
  189. package/lib/scene/styles.d.ts +0 -5
  190. package/lib/scene/styles.js +0 -69
  191. package/lib/scene/sylva-performance.d.ts +0 -11
  192. package/lib/scene/sylva-performance.js +0 -58
  193. package/lib/scene/wallpaper-character-styles.d.ts +0 -3
  194. package/lib/scene/wallpaper-character-styles.js +0 -49
  195. package/lib/scene/wallpaper-character.d.ts +0 -5
  196. package/lib/scene/wallpaper-character.js +0 -222
  197. package/lib/scene.d.ts +0 -8
  198. package/lib/scene.js +0 -8
  199. package/lib/sidebar-glass.d.ts +0 -16
  200. package/lib/sidebar-glass.js +0 -168
  201. package/lib/sidebar-heixiu-escape.d.ts +0 -44
  202. package/lib/sidebar-heixiu-escape.js +0 -340
  203. package/lib/sidebar-heixiu-roaming.d.ts +0 -27
  204. package/lib/sidebar-heixiu-roaming.js +0 -310
  205. package/lib/sidebar-reveal.d.ts +0 -8
  206. package/lib/sidebar-reveal.js +0 -59
  207. package/lib/state.d.ts +0 -21
  208. package/lib/state.js +0 -123
  209. package/lib/theme.d.ts +0 -19
  210. package/lib/theme.js +0 -188
  211. package/lib/vendor/bloub/decor.d.ts +0 -114
  212. package/lib/vendor/bloub/decor.js +0 -198
  213. package/lib/vendor/bloub/engine.d.ts +0 -213
  214. package/lib/vendor/bloub/engine.js +0 -452
  215. package/lib/vendor/bloub/expressions.d.ts +0 -35
  216. package/lib/vendor/bloub/expressions.js +0 -143
  217. package/lib/vendor/bloub/eyefit.d.ts +0 -75
  218. package/lib/vendor/bloub/eyefit.js +0 -393
  219. package/lib/vendor/bloub/face.d.ts +0 -63
  220. package/lib/vendor/bloub/face.js +0 -106
  221. package/lib/vendor/bloub/math.d.ts +0 -22
  222. package/lib/vendor/bloub/math.js +0 -36
  223. package/lib/vendor/bloub/profiles.d.ts +0 -8
  224. package/lib/vendor/bloub/profiles.js +0 -20
  225. package/lib/vendor/bloub/repere.d.ts +0 -30
  226. package/lib/vendor/bloub/repere.js +0 -32
  227. package/lib/vendor/bloub/shape.d.ts +0 -80
  228. package/lib/vendor/bloub/shape.js +0 -268
  229. package/lib/vendor/bloub/skins.d.ts +0 -36
  230. package/lib/vendor/bloub/skins.js +0 -74
  231. package/lib/vendor/bloub/states.d.ts +0 -87
  232. package/lib/vendor/bloub/states.js +0 -468
@@ -1,646 +0,0 @@
1
- import { XIAOHEI_AVATAR_2D_BLINK, XIAOHEI_AVATAR_2D_FRONT, } from '../generated-keyart.js';
2
- export const XIAOHEI_SYLVA_AVATAR_MARKER = 'data-xiaohei-avatar-model';
3
- /**
4
- * A camera-facing 2.5D character that lives inside ThreeUI's renderer. The
5
- * authored root world still owns depth and contact, while complete-frame art
6
- * keeps Xiaohei's proportions and face faithful to the reviewed illustration.
7
- */
8
- const AVATAR_ADAPTER = `
9
- /* ${XIAOHEI_SYLVA_AVATAR_MARKER}="true" */
10
- var xiaoheiAvatarArt = {
11
- base: ${JSON.stringify(XIAOHEI_AVATAR_2D_FRONT)},
12
- blink: ${JSON.stringify(XIAOHEI_AVATAR_2D_BLINK)}
13
- };
14
- var xiaoheiAvatar = null;
15
- var xiaoheiAvatarHostGroup = null;
16
- var xiaoheiAvatarHostLimbs = null;
17
- var xiaoheiAvatarPoint = new THREE.Vector3();
18
- var xiaoheiAvatarCameraLocal = new THREE.Vector3();
19
- var xiaoheiAvatarRay = new THREE.Raycaster();
20
- var xiaoheiAvatarHover = 0;
21
-
22
- function xiaoheiAvatarSmoothstep(value) {
23
- var t = Math.max(0, Math.min(1, value));
24
- return t * t * (3 - 2 * t);
25
- }
26
-
27
- function xiaoheiAvatarConfigureTexture(texture, columns) {
28
- texture.encoding = THREE.sRGBEncoding;
29
- texture.wrapS = THREE.RepeatWrapping;
30
- texture.wrapT = THREE.ClampToEdgeWrapping;
31
- texture.minFilter = THREE.LinearMipmapLinearFilter;
32
- texture.magFilter = THREE.LinearFilter;
33
- texture.generateMipmaps = true;
34
- texture.repeat.set(1 / columns, 1);
35
- texture.offset.set(0, 0);
36
- texture.needsUpdate = true;
37
- return texture;
38
- }
39
-
40
- function xiaoheiAvatarLoadTexture(source, columns, ready) {
41
- return new THREE.TextureLoader().load(
42
- source,
43
- function (texture) {
44
- xiaoheiAvatarConfigureTexture(texture, columns);
45
- if (ready) ready(texture);
46
- renderFrame();
47
- },
48
- undefined,
49
- function () {
50
- document.documentElement.dataset.xiaoheiAvatarTexture = 'load-failed';
51
- }
52
- );
53
- }
54
-
55
- function xiaoheiAvatarUseFrame(avatar, texture, columns, frame) {
56
- if (!texture || !texture.image) return;
57
- var safeFrame = Math.max(0, Math.min(columns - 1, frame | 0));
58
- texture.repeat.x = 1 / columns;
59
- texture.offset.x = safeFrame / columns;
60
- if (avatar.headMaterial.map !== texture) {
61
- avatar.headMaterial.map = texture;
62
- avatar.headMaterial.needsUpdate = true;
63
- }
64
- }
65
-
66
- function xiaoheiAvatarUseBaseTexture(avatar, texture) {
67
- avatar.materials.forEach(function (material) {
68
- material.map = texture;
69
- material.needsUpdate = true;
70
- });
71
- }
72
-
73
- function xiaoheiAvatarBuildIllustratedRig() {
74
- var bones = {
75
- root: new THREE.Bone(),
76
- torso: new THREE.Bone(),
77
- head: new THREE.Bone(),
78
- upperArmLeft: new THREE.Bone(),
79
- foreArmLeft: new THREE.Bone(),
80
- handLeft: new THREE.Bone(),
81
- upperArmRight: new THREE.Bone(),
82
- foreArmRight: new THREE.Bone(),
83
- handRight: new THREE.Bone(),
84
- pelvis: new THREE.Bone(),
85
- upperLegLeft: new THREE.Bone(),
86
- lowerLegLeft: new THREE.Bone(),
87
- footLeft: new THREE.Bone(),
88
- upperLegRight: new THREE.Bone(),
89
- lowerLegRight: new THREE.Bone(),
90
- footRight: new THREE.Bone()
91
- };
92
- var ordered = [
93
- bones.root,
94
- bones.torso,
95
- bones.head,
96
- bones.upperArmLeft,
97
- bones.foreArmLeft,
98
- bones.handLeft,
99
- bones.upperArmRight,
100
- bones.foreArmRight,
101
- bones.handRight,
102
- bones.pelvis,
103
- bones.upperLegLeft,
104
- bones.lowerLegLeft,
105
- bones.footLeft,
106
- bones.upperLegRight,
107
- bones.lowerLegRight,
108
- bones.footRight
109
- ];
110
- ordered.forEach(function (bone, index) {
111
- bone.name = 'xiaohei-2d-bone-' + index;
112
- });
113
-
114
- bones.root.add(bones.pelvis);
115
- bones.pelvis.position.set(0, 0.285, 0);
116
- bones.pelvis.add(bones.torso, bones.upperLegLeft, bones.upperLegRight);
117
- bones.torso.position.set(0, 0.155, 0);
118
- bones.torso.add(bones.head, bones.upperArmLeft, bones.upperArmRight);
119
- bones.head.position.set(0, 0.13, 0);
120
- bones.upperArmLeft.position.set(-0.125, 0.105, 0);
121
- bones.upperArmRight.position.set(0.125, 0.105, 0);
122
- bones.upperArmLeft.add(bones.foreArmLeft);
123
- bones.foreArmLeft.position.set(-0.12, -0.02, 0);
124
- bones.foreArmLeft.add(bones.handLeft);
125
- bones.handLeft.position.set(-0.09, -0.015, 0);
126
- bones.upperArmRight.add(bones.foreArmRight);
127
- bones.foreArmRight.position.set(0.12, -0.02, 0);
128
- bones.foreArmRight.add(bones.handRight);
129
- bones.handRight.position.set(0.09, -0.015, 0);
130
- bones.upperLegLeft.position.set(-0.065, -0.015, 0);
131
- bones.upperLegRight.position.set(0.065, -0.015, 0);
132
- bones.upperLegLeft.add(bones.lowerLegLeft);
133
- bones.lowerLegLeft.position.set(0, -0.115, 0);
134
- bones.lowerLegLeft.add(bones.footLeft);
135
- bones.footLeft.position.set(0, -0.105, 0);
136
- bones.upperLegRight.add(bones.lowerLegRight);
137
- bones.lowerLegRight.position.set(0, -0.115, 0);
138
- bones.lowerLegRight.add(bones.footRight);
139
- bones.footRight.position.set(0, -0.105, 0);
140
-
141
- return {
142
- root: bones.root,
143
- bones: bones,
144
- skeleton: new THREE.Skeleton(ordered),
145
- rest: {
146
- torsoY: bones.torso.position.y,
147
- headY: bones.head.position.y,
148
- pelvisY: bones.pelvis.position.y
149
- }
150
- };
151
- }
152
-
153
- function xiaoheiAvatarBuildPartGeometry(bounds, pivot, segmentsX, segmentsY) {
154
- var width = bounds[1] - bounds[0];
155
- var height = bounds[3] - bounds[2];
156
- var geometry = new THREE.PlaneGeometry(
157
- width,
158
- height,
159
- segmentsX || 1,
160
- segmentsY || 1
161
- );
162
- geometry.translate(
163
- (bounds[0] + bounds[1]) * 0.5 - pivot[0],
164
- (bounds[2] + bounds[3]) * 0.5 - pivot[1],
165
- 0
166
- );
167
- var uv = geometry.getAttribute('uv');
168
- for (var vertex = 0; vertex < uv.count; vertex += 1) {
169
- uv.setXY(
170
- vertex,
171
- bounds[0] + 0.5 + uv.getX(vertex) * width,
172
- bounds[2] + uv.getY(vertex) * height
173
- );
174
- }
175
- uv.needsUpdate = true;
176
- return geometry;
177
- }
178
-
179
- function xiaoheiAvatarBuildPart(bone, definition, materials, hitMeshes) {
180
- var material = new THREE.MeshBasicMaterial({
181
- color: 0xffffff,
182
- transparent: true,
183
- opacity: 0,
184
- alphaTest: 0.026,
185
- depthTest: true,
186
- depthWrite: false,
187
- side: THREE.DoubleSide
188
- });
189
- material.toneMapped = false;
190
- var geometry = xiaoheiAvatarBuildPartGeometry(
191
- definition.bounds,
192
- definition.pivot,
193
- definition.segmentsX,
194
- definition.segmentsY
195
- );
196
- var mesh = new THREE.Mesh(geometry, material);
197
- mesh.name = 'xiaohei-avatar-part-' + definition.name;
198
- mesh.position.z = definition.depth || 0;
199
- mesh.renderOrder = definition.order;
200
- mesh.frustumCulled = false;
201
- bone.add(mesh);
202
- materials.push(material);
203
- hitMeshes.push(mesh);
204
- return mesh;
205
- }
206
-
207
- function xiaoheiAvatarBuildSkinnedPart(model, rig, definition, materials, hitMeshes) {
208
- var material = new THREE.MeshBasicMaterial({
209
- color: 0xffffff,
210
- transparent: true,
211
- opacity: 0,
212
- alphaTest: 0.026,
213
- depthTest: true,
214
- depthWrite: false,
215
- side: THREE.DoubleSide
216
- });
217
- material.toneMapped = false;
218
- var geometry = xiaoheiAvatarBuildPartGeometry(
219
- definition.bounds,
220
- [0, 0],
221
- definition.segmentsX,
222
- definition.segmentsY
223
- );
224
- var position = geometry.getAttribute('position');
225
- var skinIndex = new Uint16Array(position.count * 4);
226
- var skinWeight = new Float32Array(position.count * 4);
227
- for (var vertex = 0; vertex < position.count; vertex += 1) {
228
- var along = definition.axis === 'x'
229
- ? (position.getX(vertex) - definition.origin) * definition.direction
230
- : (definition.origin - position.getY(vertex));
231
- var first = definition.chain[0];
232
- var second = first;
233
- var firstWeight = 1;
234
- if (along > definition.joints[1] - definition.blend) {
235
- first = definition.chain[2];
236
- second = definition.chain[1];
237
- firstWeight = xiaoheiAvatarSmoothstep(
238
- (along - definition.joints[1] + definition.blend) / (definition.blend * 2)
239
- );
240
- } else if (along > definition.joints[0] - definition.blend) {
241
- first = definition.chain[1];
242
- second = definition.chain[0];
243
- firstWeight = xiaoheiAvatarSmoothstep(
244
- (along - definition.joints[0] + definition.blend) / (definition.blend * 2)
245
- );
246
- }
247
- var offset = vertex * 4;
248
- skinIndex[offset] = first;
249
- skinIndex[offset + 1] = second;
250
- skinWeight[offset] = firstWeight;
251
- skinWeight[offset + 1] = 1 - firstWeight;
252
- }
253
- geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndex, 4));
254
- geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeight, 4));
255
- var mesh = new THREE.SkinnedMesh(geometry, material);
256
- mesh.name = 'xiaohei-avatar-part-' + definition.name;
257
- mesh.position.z = definition.depth || 0;
258
- mesh.renderOrder = definition.order;
259
- mesh.frustumCulled = false;
260
- mesh.bind(rig.skeleton);
261
- model.add(mesh);
262
- materials.push(material);
263
- hitMeshes.push(mesh);
264
- return mesh;
265
- }
266
-
267
- function xiaoheiAvatarUpdateRig(avatar, now) {
268
- var bones = avatar.rig.bones;
269
- var rest = avatar.rig.rest;
270
- var seconds = (now - avatar.motionStarted) * 0.001;
271
- var breath = REDUCED ? 0 : Math.sin(seconds * 1.72);
272
- var slow = REDUCED ? 0 : Math.sin(seconds * 0.63 + 0.8);
273
- var delayed = REDUCED ? 0 : Math.sin(seconds * 1.72 - 0.34);
274
-
275
- /* The source illustration is a T pose. Rotate the complete painted sleeve,
276
- cuff and hand regions as one articulated chain so clothing never floats
277
- away from the limb it belongs to. */
278
- bones.root.rotation.set(0, 0, 0);
279
- bones.root.position.set(0, 0, 0);
280
- bones.torso.position.y = rest.torsoY + breath * 0.0022;
281
- bones.torso.rotation.set(0, 0, slow * 0.008);
282
- bones.torso.scale.set(1, 1 + breath * 0.0035, 1);
283
- bones.head.position.y = rest.headY;
284
- bones.head.rotation.set(0, 0, -slow * 0.014 + delayed * 0.004);
285
-
286
- bones.upperArmLeft.rotation.set(0, 0, 1.39 + breath * 0.012 + slow * 0.008);
287
- bones.foreArmLeft.rotation.set(0, 0, -0.075 + delayed * 0.009);
288
- bones.handLeft.rotation.set(0, 0, 0.035 - delayed * 0.012);
289
- bones.upperArmRight.rotation.set(0, 0, -1.39 - breath * 0.012 + slow * 0.008);
290
- bones.foreArmRight.rotation.set(0, 0, 0.075 - delayed * 0.009);
291
- bones.handRight.rotation.set(0, 0, -0.035 + delayed * 0.012);
292
-
293
- bones.pelvis.position.y = rest.pelvisY;
294
- bones.pelvis.rotation.set(0, 0, -slow * 0.004);
295
- bones.upperLegLeft.rotation.set(0, 0, slow * 0.006);
296
- bones.lowerLegLeft.rotation.set(0, 0, -slow * 0.004);
297
- bones.footLeft.rotation.set(0, 0, -slow * 0.002);
298
- bones.upperLegRight.rotation.set(0, 0, slow * 0.006);
299
- bones.lowerLegRight.rotation.set(0, 0, -slow * 0.004);
300
- bones.footRight.rotation.set(0, 0, -slow * 0.002);
301
- bones.root.updateMatrixWorld(true);
302
- }
303
-
304
- function xiaoheiAvatarBuildModel() {
305
- var root = new THREE.Group();
306
- root.name = 'xiaohei-avatar-2-5d-root-v1';
307
- var model = new THREE.Group();
308
- model.name = 'xiaohei-avatar-2-5d-model-v1';
309
- root.add(model);
310
-
311
- var rig = xiaoheiAvatarBuildIllustratedRig();
312
- var materials = [];
313
- var hitMeshes = [];
314
- model.add(rig.root);
315
- rig.root.updateMatrixWorld(true);
316
-
317
- var parts = {};
318
- parts.armLeft = xiaoheiAvatarBuildSkinnedPart(model, rig, {
319
- name: 'arm-left-with-sleeve', bounds: [-0.42, -0.105, 0.425, 0.62],
320
- axis: 'x', origin: -0.125, direction: -1, chain: [3, 4, 5],
321
- joints: [0.12, 0.21], blend: 0.025,
322
- order: 4, segmentsX: 24, segmentsY: 8
323
- }, materials, hitMeshes);
324
- parts.armRight = xiaoheiAvatarBuildSkinnedPart(model, rig, {
325
- name: 'arm-right-with-sleeve', bounds: [0.105, 0.42, 0.425, 0.62],
326
- axis: 'x', origin: 0.125, direction: 1, chain: [6, 7, 8],
327
- joints: [0.12, 0.21], blend: 0.025,
328
- order: 4, segmentsX: 24, segmentsY: 8
329
- }, materials, hitMeshes);
330
- parts.legLeft = xiaoheiAvatarBuildSkinnedPart(model, rig, {
331
- name: 'leg-left-with-shoe', bounds: [-0.175, -0.005, 0.0, 0.32],
332
- axis: 'y', origin: 0.27, direction: 1, chain: [10, 11, 12],
333
- joints: [0.115, 0.22], blend: 0.022,
334
- order: 3, segmentsX: 8, segmentsY: 24
335
- }, materials, hitMeshes);
336
- parts.legRight = xiaoheiAvatarBuildSkinnedPart(model, rig, {
337
- name: 'leg-right-with-shoe', bounds: [0.005, 0.175, 0.0, 0.32],
338
- axis: 'y', origin: 0.27, direction: 1, chain: [13, 14, 15],
339
- joints: [0.115, 0.22], blend: 0.022,
340
- order: 3, segmentsX: 8, segmentsY: 24
341
- }, materials, hitMeshes);
342
- parts.torso = xiaoheiAvatarBuildPart(rig.bones.torso, {
343
- name: 'torso-clothing', bounds: [-0.19, 0.19, 0.225, 0.65],
344
- pivot: [0, 0.44], order: 6
345
- }, materials, hitMeshes);
346
- parts.head = xiaoheiAvatarBuildPart(rig.bones.head, {
347
- name: 'head', bounds: [-0.265, 0.265, 0.555, 1.0],
348
- pivot: [0, 0.57], order: 8, segmentsX: 24, segmentsY: 24, depth: 0.006
349
- }, materials, hitMeshes);
350
- var basePositions = parts.head.geometry.getAttribute('position').array.slice();
351
-
352
- var scanMaterial = new THREE.MeshBasicMaterial({
353
- color: 0x9bf1c9,
354
- transparent: true,
355
- opacity: 0,
356
- depthTest: true,
357
- depthWrite: false,
358
- blending: THREE.AdditiveBlending,
359
- side: THREE.DoubleSide
360
- });
361
- scanMaterial.toneMapped = false;
362
- var scanLine = new THREE.Mesh(new THREE.PlaneGeometry(0.72, 0.012), scanMaterial);
363
- scanLine.name = 'xiaohei-avatar-scan-line-v1';
364
- scanLine.position.set(-0.02, 0.02, 0.024);
365
- scanLine.renderOrder = 10;
366
- model.add(scanLine);
367
-
368
- var avatar = {
369
- root: root,
370
- model: model,
371
- rig: rig,
372
- parts: parts,
373
- headMesh: parts.head,
374
- headMaterial: parts.head.material,
375
- materials: materials,
376
- hitMeshes: hitMeshes,
377
- basePositions: basePositions,
378
- scanLine: scanLine,
379
- scanMaterial: scanMaterial,
380
- textures: {},
381
- ready: false,
382
- builtAt: performance.now(),
383
- motionStarted: performance.now(),
384
- anchorT: 0.38,
385
- reaction: '',
386
- reactionStarted: 0,
387
- reactionUntil: 0,
388
- hoverEar: '',
389
- earLeftAmount: 0,
390
- earRightAmount: 0,
391
- nextBlink: performance.now() + 3200 + Math.random() * 2600,
392
- blinkUntil: 0,
393
- nextEar: performance.now() + 8000 + Math.random() * 9000
394
- };
395
-
396
- avatar.textures.base = xiaoheiAvatarLoadTexture(xiaoheiAvatarArt.base, 1, function (texture) {
397
- avatar.ready = true;
398
- avatar.builtAt = performance.now();
399
- xiaoheiAvatarUseBaseTexture(avatar, texture);
400
- xiaoheiAvatarUseFrame(avatar, texture, 1, 0);
401
- document.documentElement.dataset.xiaoheiAvatarTexture = 'illustrated-2-5d-v1';
402
- document.documentElement.dataset.xiaoheiAvatarScan = REDUCED ? 'skipped' : 'active';
403
- });
404
- avatar.textures.blink = xiaoheiAvatarLoadTexture(xiaoheiAvatarArt.blink, 1);
405
- return avatar;
406
- }
407
-
408
- function xiaoheiAvatarSampleAt(t, target) {
409
- if (!xiaoheiAvatarHostLimbs || !xiaoheiAvatarHostLimbs[0]) return false;
410
- var limb = xiaoheiAvatarHostLimbs[0];
411
- if (limb.grid && limb.S && limb.R) {
412
- var row = Math.max(0, Math.min(limb.S, t * limb.S));
413
- var row0 = Math.min(limb.S - 1, Math.floor(row));
414
- var row1 = Math.min(limb.S, row0 + 1);
415
- var blend = row - row0;
416
- var stride = limb.R + 1;
417
- var highestY = -Infinity;
418
- for (var ringIndex = 0; ringIndex < limb.R; ringIndex += 1) {
419
- var offset0 = (row0 * stride + ringIndex) * 3;
420
- var offset1 = (row1 * stride + ringIndex) * 3;
421
- var surfaceY = limb.grid[offset0 + 1]
422
- + (limb.grid[offset1 + 1] - limb.grid[offset0 + 1]) * blend;
423
- if (surfaceY <= highestY) continue;
424
- highestY = surfaceY;
425
- target.set(
426
- limb.grid[offset0] + (limb.grid[offset1] - limb.grid[offset0]) * blend,
427
- surfaceY + 0.018,
428
- limb.grid[offset0 + 2]
429
- + (limb.grid[offset1 + 2] - limb.grid[offset0 + 2]) * blend
430
- );
431
- }
432
- return highestY > -Infinity;
433
- }
434
- target.copy(limb.curve.getPointAt(t));
435
- var moss = limb.moss ? limb.moss(t) : 0;
436
- var radius = limb.rw(t) + moss * 0.52;
437
- if (limb.sink) target.y -= moss * limb.sink;
438
- target.y += radius + 0.02;
439
- return true;
440
- }
441
-
442
- function xiaoheiAvatarBeginReaction(avatar, reaction, now, duration) {
443
- if (avatar.reaction && now < avatar.reactionUntil) return;
444
- avatar.reaction = reaction;
445
- avatar.reactionStarted = now;
446
- avatar.reactionUntil = now + duration;
447
- document.documentElement.dataset.xiaoheiAvatarAction = reaction + '-2-5d';
448
- }
449
-
450
- function xiaoheiAvatarUpdatePointer(avatar, now) {
451
- var hit = null;
452
- if (avatar.ready && ndc.x >= -1.2 && ndc.x <= 1.2 && ndc.y >= -1.2 && ndc.y <= 1.2) {
453
- xiaoheiAvatarRay.setFromCamera(ndc, camera);
454
- var intersections = xiaoheiAvatarRay.intersectObjects(avatar.hitMeshes, false);
455
- if (intersections.length) hit = intersections[0];
456
- }
457
- xiaoheiAvatarHover += ((hit ? 1 : 0) - xiaoheiAvatarHover) * (hit ? 0.16 : 0.08);
458
- var ear = '';
459
- if (hit && hit.uv) {
460
- var leftDistance = Math.hypot(
461
- (hit.uv.x - 0.35) / 0.11,
462
- (hit.uv.y - 0.85) / 0.16
463
- );
464
- var rightDistance = Math.hypot(
465
- (hit.uv.x - 0.64) / 0.11,
466
- (hit.uv.y - 0.84) / 0.16
467
- );
468
- if (leftDistance <= 1 || rightDistance <= 1) {
469
- ear = leftDistance <= rightDistance ? 'ear-left' : 'ear-right';
470
- }
471
- }
472
- if (ear && ear !== avatar.hoverEar && now >= avatar.reactionUntil) {
473
- xiaoheiAvatarBeginReaction(avatar, ear, now, 560);
474
- }
475
- avatar.hoverEar = ear;
476
- document.documentElement.dataset.xiaoheiAvatarHover = xiaoheiAvatarHover > 0.08 ? 'true' : 'false';
477
- }
478
-
479
- function xiaoheiAvatarDeformEar(avatar, centerU, centerV, pivotU, pivotV, amount) {
480
- if (Math.abs(amount) < 0.0001) return;
481
- var position = avatar.headMesh.geometry.getAttribute('position');
482
- var uv = avatar.headMesh.geometry.getAttribute('uv');
483
- for (var vertex = 0; vertex < position.count; vertex += 1) {
484
- var du = (uv.getX(vertex) - centerU) / 0.13;
485
- var dv = (uv.getY(vertex) - centerV) / 0.18;
486
- var distance = Math.hypot(du, dv);
487
- if (distance >= 1) continue;
488
- var influence = xiaoheiAvatarSmoothstep(1 - distance);
489
- var angle = amount * influence;
490
- var x = position.getX(vertex) - (pivotU - 0.5);
491
- var localPivotY = pivotV - 0.57;
492
- var y = position.getY(vertex) - localPivotY;
493
- var cosine = Math.cos(angle);
494
- var sine = Math.sin(angle);
495
- position.setXY(
496
- vertex,
497
- x * cosine - y * sine + pivotU - 0.5,
498
- x * sine + y * cosine + localPivotY
499
- );
500
- }
501
- }
502
-
503
- function xiaoheiAvatarUpdateEars(avatar) {
504
- var position = avatar.headMesh.geometry.getAttribute('position');
505
- position.array.set(avatar.basePositions);
506
- xiaoheiAvatarDeformEar(avatar, 0.35, 0.85, 0.39, 0.73, avatar.earLeftAmount * 0.12);
507
- xiaoheiAvatarDeformEar(avatar, 0.64, 0.84, 0.60, 0.73, avatar.earRightAmount * -0.12);
508
- position.needsUpdate = true;
509
- }
510
-
511
- function xiaoheiAvatarUpdateVisual(avatar, now) {
512
- var blinking = now < avatar.blinkUntil;
513
- if (!REDUCED && !avatar.reaction && now >= avatar.nextBlink) {
514
- avatar.blinkUntil = now + 135;
515
- avatar.nextBlink = now + 3800 + Math.random() * 3600;
516
- blinking = true;
517
- }
518
- if (!REDUCED && !avatar.reaction && now >= avatar.nextEar) {
519
- xiaoheiAvatarBeginReaction(
520
- avatar,
521
- Math.random() < 0.5 ? 'ear-left' : 'ear-right',
522
- now,
523
- 620
524
- );
525
- avatar.nextEar = now + 8000 + Math.random() * 9000;
526
- }
527
-
528
- if (avatar.reaction && now >= avatar.reactionUntil) {
529
- avatar.reaction = '';
530
- document.documentElement.dataset.xiaoheiAvatarAction = 'idle-2-5d';
531
- }
532
-
533
- avatar.earLeftAmount = 0;
534
- avatar.earRightAmount = 0;
535
- if (avatar.reaction) {
536
- var reactionProgress = Math.max(0, Math.min(0.999,
537
- (now - avatar.reactionStarted) / (avatar.reactionUntil - avatar.reactionStarted)
538
- ));
539
- var earPulse = Math.sin(reactionProgress * Math.PI)
540
- * Math.sin(reactionProgress * Math.PI * 2.5);
541
- if (avatar.reaction === 'ear-left') {
542
- avatar.earLeftAmount = earPulse;
543
- } else if (avatar.reaction === 'ear-right') {
544
- avatar.earRightAmount = earPulse;
545
- }
546
- }
547
- if (blinking) {
548
- xiaoheiAvatarUseFrame(avatar, avatar.textures.blink, 1, 0);
549
- } else {
550
- xiaoheiAvatarUseFrame(avatar, avatar.textures.base, 1, 0);
551
- }
552
- xiaoheiAvatarUpdateEars(avatar);
553
- }
554
-
555
- function xiaoheiAvatarBuild() {
556
- if (!xiaoheiAvatarHostGroup || !xiaoheiAvatarHostLimbs || xiaoheiAvatar) return;
557
- xiaoheiAvatar = xiaoheiAvatarBuildModel();
558
- xiaoheiAvatarHostGroup.add(xiaoheiAvatar.root);
559
- xiaoheiAvatarSampleAt(xiaoheiAvatar.anchorT, xiaoheiAvatarPoint);
560
- xiaoheiAvatar.root.position.copy(xiaoheiAvatarPoint);
561
- document.documentElement.dataset.xiaoheiAvatarReady = 'true';
562
- document.documentElement.dataset.xiaoheiAvatarMotion = 'illustrated-2-5d-v1';
563
- document.documentElement.dataset.xiaoheiAvatarAction = 'idle-2-5d';
564
- document.documentElement.dataset.xiaoheiAvatarPose = 'idle';
565
- renderFrame();
566
- }
567
-
568
- function xiaoheiAvatarUpdate() {
569
- if (!xiaoheiAvatar || !camera || !xiaoheiAvatarHostGroup) return;
570
- var avatar = xiaoheiAvatar;
571
- var now = performance.now();
572
- xiaoheiAvatarSampleAt(avatar.anchorT, xiaoheiAvatarPoint);
573
- avatar.root.position.copy(xiaoheiAvatarPoint);
574
- var displayHeight = NARROW.matches ? 2.08 : 1.72;
575
- avatar.model.scale.setScalar(displayHeight);
576
- avatar.model.position.y = 0;
577
-
578
- xiaoheiAvatarCameraLocal.copy(camera.position);
579
- xiaoheiAvatarHostGroup.worldToLocal(xiaoheiAvatarCameraLocal);
580
- var cameraDx = xiaoheiAvatarCameraLocal.x - xiaoheiAvatarPoint.x;
581
- var cameraDz = xiaoheiAvatarCameraLocal.z - xiaoheiAvatarPoint.z;
582
- avatar.model.rotation.y = Math.atan2(cameraDx, cameraDz);
583
-
584
- if (avatar.ready) {
585
- var reveal = REDUCED ? 1 : xiaoheiAvatarSmoothstep((now - avatar.builtAt) / 860);
586
- avatar.materials.forEach(function (material) {
587
- material.opacity = reveal;
588
- });
589
- avatar.scanLine.visible = reveal < 0.995 && !REDUCED;
590
- avatar.scanLine.position.y = 0.04 + reveal * 0.80;
591
- avatar.scanMaterial.opacity = Math.sin(reveal * Math.PI) * 0.42;
592
- if (reveal >= 0.995 && document.documentElement.dataset.xiaoheiAvatarScan !== 'complete') {
593
- document.documentElement.dataset.xiaoheiAvatarScan = 'complete';
594
- }
595
- xiaoheiAvatarUpdatePointer(avatar, now);
596
- xiaoheiAvatarUpdateVisual(avatar, now);
597
- xiaoheiAvatarUpdateRig(avatar, now);
598
- }
599
- }
600
-
601
- var xiaoheiAvatarOriginalAssembleRoot = assembleRoot;
602
- assembleRoot = function (limbs, options) {
603
- var group = xiaoheiAvatarOriginalAssembleRoot(limbs, options);
604
- if (options && options.order === 0) {
605
- xiaoheiAvatarHostLimbs = limbs;
606
- xiaoheiAvatarHostGroup = group;
607
- }
608
- return group;
609
- };
610
-
611
- var xiaoheiAvatarOriginalRenderFrame = renderFrame;
612
- renderFrame = function () {
613
- xiaoheiAvatarUpdate();
614
- xiaoheiAvatarOriginalRenderFrame();
615
- };
616
-
617
- var xiaoheiAvatarOriginalBuild = build;
618
- build = function () {
619
- xiaoheiAvatarOriginalBuild();
620
- xiaoheiAvatarBuild();
621
- };
622
- `;
623
- /** Inject the renderer-sharing 2.5D avatar without editing registered ThreeUI files. */
624
- export function injectXiaoheiSylvaAvatarModel(source) {
625
- if (source.includes(`${XIAOHEI_SYLVA_AVATAR_MARKER}="true"`))
626
- return source;
627
- const runtimeEnd = source.lastIndexOf('\n})();\n</script>');
628
- if (runtimeEnd < 0)
629
- return source;
630
- return `${source.slice(0, runtimeEnd)}${AVATAR_ADAPTER}${source.slice(runtimeEnd)}`;
631
- }
632
- /** Prepare the detached iframe so the avatar exists on its first WebGL boot. */
633
- export function prepareXiaoheiSylvaAvatarFrame(frame) {
634
- const source = frame.getAttribute('srcdoc');
635
- if (source === null)
636
- return false;
637
- const modeledSource = injectXiaoheiSylvaAvatarModel(source);
638
- if (modeledSource === source && !source.includes(`${XIAOHEI_SYLVA_AVATAR_MARKER}="true"`)) {
639
- return false;
640
- }
641
- frame.dataset.xiaoheiAvatarModel = 'true';
642
- if (modeledSource !== source)
643
- frame.setAttribute('srcdoc', modeledSource);
644
- return true;
645
- }
646
- //# sourceMappingURL=avatar-model.js.map