@streaming-cdn/rtc-web 1.3.25 → 1.3.26

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RTC Web SDK 1.3.25
1
+ # RTC Web SDK 1.3.26
2
2
 
3
3
  The customer package contains compiled ESM/UMD JavaScript and TypeScript declarations. It intentionally excludes implementation source and source maps. Example source remains available under `examples/`.
4
4
 
@@ -357,6 +357,20 @@ operational diagnostics. Tokens, SDP, media, and chat content are never part of
357
357
  that report. Set `reportSignalingDiagnostics: false` only when replacing this
358
358
  with an application-owned diagnostics pipeline.
359
359
 
360
+ ## 1.3.26 notes
361
+
362
+ - **VRM avatars are framed from the model's own measurements.** The bust
363
+ camera in `avatar-vrm` was fixed at a 0.42 m window aimed at the head
364
+ joint — which sits at the *bottom* of the skull — so characters with tall
365
+ hair or accessories had their crowns cropped, and big-headed models filled
366
+ the whole canvas and rendered far larger than the built-in avatar when
367
+ overlaid. `createVrmStage` now measures each model (head joint from the
368
+ humanoid, crown from the scene bounds, hair included) and frames the bust
369
+ so the skull spans ~38% of the canvas with its centre at 42% from the top —
370
+ the exact contract `vrmAvatarRenderer`'s overlay math expects. Every
371
+ character now appears the same size as the built-in stylized avatar,
372
+ whatever its proportions. The framing rule is exported as `frameVrmBust()`.
373
+
360
374
  ## 1.3.25 notes
361
375
 
362
376
  - **B21 — per-peer quality no longer ratchets down on bandwidth-pinned
@@ -9,6 +9,29 @@ export interface VrmStage {
9
9
  applyAndRender(rig: AvatarRig, options?: VrmRenderOptions): void;
10
10
  dispose(): void;
11
11
  }
12
+ /**
13
+ * Bust framing computed from the model's own measurements.
14
+ *
15
+ * Characters do not share proportions: the head joint sits at the bottom of
16
+ * the skull, and between a chibi and a tall model the joint-to-crown distance
17
+ * (hair and accessories included) spans several fold. A fixed camera cropped
18
+ * tall hair off and let big heads fill the whole canvas, which the overlay
19
+ * then multiplied into an avatar larger than the screen.
20
+ *
21
+ * The contract with `vrmAvatarRenderer` is proportional: the skull spans
22
+ * roughly 38% of the canvas (2 of the 5.2 head radii the overlay paints) with
23
+ * its centre at 42% from the top — the same size and seat as the built-in
24
+ * stylized head, so switching characters never changes how big the avatar
25
+ * appears over the person.
26
+ */
27
+ export declare function frameVrmBust(measure: {
28
+ headY: number;
29
+ crownY: number;
30
+ }): {
31
+ windowHeight: number;
32
+ lookY: number;
33
+ distance: number;
34
+ };
12
35
  /**
13
36
  * Adapts a VrmStage to the SDK's pluggable `AvatarRenderer`, so
14
37
  * `createAvatarPipeline` can publish a VRM character instead of the built-in
@@ -1,61 +1,68 @@
1
- import * as l from "three";
1
+ import * as d from "three";
2
2
  import { GLTFLoader as L } from "three/examples/jsm/loaders/GLTFLoader.js";
3
- import { VRMLoaderPlugin as A, VRMUtils as k } from "@pixiv/three-vrm";
4
- function M(t, c) {
3
+ import { VRMLoaderPlugin as g, VRMUtils as w } from "@pixiv/three-vrm";
4
+ function A(n) {
5
+ const o = n.crownY - n.headY, t = o > 0.05 && o < 1.5 ? o : 0.25, r = t * 2.1, p = n.headY + t * 0.45 - r * 0.08, s = r / 2 / Math.tan(28 / 2 * (Math.PI / 180));
6
+ return { windowHeight: r, lookY: p, distance: s };
7
+ }
8
+ function C(n, o) {
5
9
  return {
6
- render(n, p, s, m, o) {
7
- if (t.applyAndRender(p, c), o) {
8
- const a = o.radius * 5.2;
9
- n.drawImage(t.canvas, o.x - a / 2, o.y - a * 0.42, a, a);
10
+ render(t, r, c, p, s) {
11
+ if (n.applyAndRender(r, o), s) {
12
+ const a = s.radius * 5.2;
13
+ t.drawImage(n.canvas, s.x - a / 2, s.y - a * 0.42, a, a);
10
14
  } else {
11
- const a = Math.min(s, m);
12
- n.drawImage(t.canvas, (s - a) / 2, (m - a) / 2, a, a);
15
+ const a = Math.min(c, p);
16
+ t.drawImage(n.canvas, (c - a) / 2, (p - a) / 2, a, a);
13
17
  }
14
18
  },
15
19
  dispose() {
16
- t.dispose();
20
+ n.dispose();
17
21
  }
18
22
  };
19
23
  }
20
- async function g(t, c = 512) {
21
- const n = document.createElement("canvas");
22
- n.width = c, n.height = c;
23
- const p = new l.WebGLRenderer({ canvas: n, alpha: !0, antialias: !0 });
24
- p.setClearColor(0, 0);
25
- const s = new l.Scene();
26
- s.add(new l.AmbientLight(16777215, 1.1));
27
- const m = new l.DirectionalLight(16777215, 1.4);
28
- m.position.set(0.5, 1.2, 1.5), s.add(m);
29
- const o = new l.PerspectiveCamera(28, 1, 0.1, 20), a = new L();
30
- a.register((e) => new A(e));
31
- const w = await a.parseAsync(t, ""), i = w.userData.vrm;
32
- k.removeUnnecessaryVertices(w.scene), k.combineSkeletons(w.scene), k.rotateVRM0(i), s.add(i.scene);
33
- const u = i.humanoid?.getNormalizedBoneNode("head"), h = new l.Vector3(0, 1.35, 0);
34
- u && u.getWorldPosition(h), o.position.set(0, h.y + 0.03, 0.85), o.lookAt(0, h.y + 0.01, 0);
35
- const f = new l.Object3D();
36
- f.position.set(0, h.y, 2), s.add(f), i.lookAt && (i.lookAt.target = f);
37
- const b = new l.Clock();
24
+ async function G(n, o = 512) {
25
+ const t = document.createElement("canvas");
26
+ t.width = o, t.height = o;
27
+ const r = new d.WebGLRenderer({ canvas: t, alpha: !0, antialias: !0 });
28
+ r.setClearColor(0, 0);
29
+ const c = new d.Scene();
30
+ c.add(new d.AmbientLight(16777215, 1.1));
31
+ const p = new d.DirectionalLight(16777215, 1.4);
32
+ p.position.set(0.5, 1.2, 1.5), c.add(p);
33
+ const s = new d.PerspectiveCamera(28, 1, 0.1, 20), a = new L();
34
+ a.register((e) => new g(e));
35
+ const k = await a.parseAsync(n, ""), i = k.userData.vrm;
36
+ w.removeUnnecessaryVertices(k.scene), w.combineSkeletons(k.scene), w.rotateVRM0(i), c.add(i.scene);
37
+ const u = i.humanoid?.getNormalizedBoneNode("head"), h = new d.Vector3(0, 1.35, 0);
38
+ u && u.getWorldPosition(h), i.scene.updateWorldMatrix(!0, !0);
39
+ const R = new d.Box3().setFromObject(i.scene), V = Number.isFinite(R.max.y) ? R.max.y : h.y + 0.25, y = A({ headY: h.y, crownY: V });
40
+ s.position.set(0, y.lookY, y.distance), s.lookAt(0, y.lookY, 0);
41
+ const f = new d.Object3D();
42
+ f.position.set(0, h.y, 2), c.add(f), i.lookAt && (i.lookAt.target = f);
43
+ const M = new d.Clock();
38
44
  return {
39
- canvas: n,
40
- applyAndRender(e, R) {
41
- const y = R?.headGain ?? 0.9, r = i.expressionManager;
42
- if (r) {
43
- const V = r.expressionMap ?? {}, d = (v) => !!V[v];
44
- d("blinkLeft") || d("blinkRight") ? (r.setValue("blinkLeft", e.blinkLeft), r.setValue("blinkRight", e.blinkRight)) : d("blink") && r.setValue("blink", (e.blinkLeft + e.blinkRight) / 2), d("aa") && r.setValue("aa", Math.max(0, e.jawOpen)), d("happy") && r.setValue("happy", Math.max(0, e.smile)), d("angry") && r.setValue("angry", Math.max(0, -e.smile) * 0.6);
45
+ canvas: t,
46
+ applyAndRender(e, Y) {
47
+ const b = Y?.headGain ?? 0.9, l = i.expressionManager;
48
+ if (l) {
49
+ const v = l.expressionMap ?? {}, m = (x) => !!v[x];
50
+ m("blinkLeft") || m("blinkRight") ? (l.setValue("blinkLeft", e.blinkLeft), l.setValue("blinkRight", e.blinkRight)) : m("blink") && l.setValue("blink", (e.blinkLeft + e.blinkRight) / 2), m("aa") && l.setValue("aa", Math.max(0, e.jawOpen)), m("happy") && l.setValue("happy", Math.max(0, e.smile)), m("angry") && l.setValue("angry", Math.max(0, -e.smile) * 0.6);
45
51
  }
46
- u && u.rotation.set(-e.headPitch * y, e.headYaw * y, -e.headRoll * y), f.position.set(e.pupilX * 1.2, h.y - e.pupilY * 0.8, 2), i.update(b.getDelta()), p.render(s, o);
52
+ u && u.rotation.set(-e.headPitch * b, e.headYaw * b, -e.headRoll * b), f.position.set(e.pupilX * 1.2, h.y - e.pupilY * 0.8, 2), i.update(M.getDelta()), r.render(c, s);
47
53
  },
48
54
  dispose() {
49
- k.deepDispose(i.scene), p.dispose();
55
+ w.deepDispose(i.scene), r.dispose();
50
56
  }
51
57
  };
52
58
  }
53
- async function D(t, c = {}) {
54
- const n = await g(t, c.size ?? 640);
55
- return M(n, { headGain: c.headGain });
59
+ async function B(n, o = {}) {
60
+ const t = await G(n, o.size ?? 640);
61
+ return C(t, { headGain: o.headGain });
56
62
  }
57
63
  export {
58
- D as createVrmAvatarRenderer,
59
- g as createVrmStage,
60
- M as vrmAvatarRenderer
64
+ B as createVrmAvatarRenderer,
65
+ G as createVrmStage,
66
+ A as frameVrmBust,
67
+ C as vrmAvatarRenderer
61
68
  };
@@ -1 +1 @@
1
- (function(s,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("three"),require("three/examples/jsm/loaders/GLTFLoader.js"),require("@pixiv/three-vrm")):typeof define=="function"&&define.amd?define(["exports","three","three/examples/jsm/loaders/GLTFLoader.js","@pixiv/three-vrm"],f):(s=typeof globalThis<"u"?globalThis:s||self,f(s.StreamingCdnRtcAvatarVrm={},s.THREE,s.THREE,s.THREE_VRM))})(this,(function(s,f,M,m){"use strict";function L(e){const i=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(i,t,r.get?r:{enumerable:!0,get:()=>e[t]})}}return i.default=e,Object.freeze(i)}const o=L(f);function w(e,i){return{render(t,r,d,h,c){if(e.applyAndRender(r,i),c){const a=c.radius*5.2;t.drawImage(e.canvas,c.x-a/2,c.y-a*.42,a,a)}else{const a=Math.min(d,h);t.drawImage(e.canvas,(d-a)/2,(h-a)/2,a,a)}},dispose(){e.dispose()}}}async function V(e,i=512){const t=document.createElement("canvas");t.width=i,t.height=i;const r=new o.WebGLRenderer({canvas:t,alpha:!0,antialias:!0});r.setClearColor(0,0);const d=new o.Scene;d.add(new o.AmbientLight(16777215,1.1));const h=new o.DirectionalLight(16777215,1.4);h.position.set(.5,1.2,1.5),d.add(h);const c=new o.PerspectiveCamera(28,1,.1,20),a=new M.GLTFLoader;a.register(n=>new m.VRMLoaderPlugin(n));const b=await a.parseAsync(e,""),l=b.userData.vrm;m.VRMUtils.removeUnnecessaryVertices(b.scene),m.VRMUtils.combineSkeletons(b.scene),m.VRMUtils.rotateVRM0(l),d.add(l.scene);const y=l.humanoid?.getNormalizedBoneNode("head"),R=new o.Vector3(0,1.35,0);y&&y.getWorldPosition(R),c.position.set(0,R.y+.03,.85),c.lookAt(0,R.y+.01,0);const v=new o.Object3D;v.position.set(0,R.y,2),d.add(v),l.lookAt&&(l.lookAt.target=v);const j=new o.Clock;return{canvas:t,applyAndRender(n,A){const k=A?.headGain??.9,p=l.expressionManager;if(p){const T=p.expressionMap??{},u=x=>!!T[x];u("blinkLeft")||u("blinkRight")?(p.setValue("blinkLeft",n.blinkLeft),p.setValue("blinkRight",n.blinkRight)):u("blink")&&p.setValue("blink",(n.blinkLeft+n.blinkRight)/2),u("aa")&&p.setValue("aa",Math.max(0,n.jawOpen)),u("happy")&&p.setValue("happy",Math.max(0,n.smile)),u("angry")&&p.setValue("angry",Math.max(0,-n.smile)*.6)}y&&y.rotation.set(-n.headPitch*k,n.headYaw*k,-n.headRoll*k),v.position.set(n.pupilX*1.2,R.y-n.pupilY*.8,2),l.update(j.getDelta()),r.render(d,c)},dispose(){m.VRMUtils.deepDispose(l.scene),r.dispose()}}}async function g(e,i={}){const t=await V(e,i.size??640);return w(t,{headGain:i.headGain})}s.createVrmAvatarRenderer=g,s.createVrmStage=V,s.vrmAvatarRenderer=w,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(s,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("three"),require("three/examples/jsm/loaders/GLTFLoader.js"),require("@pixiv/three-vrm")):typeof define=="function"&&define.amd?define(["exports","three","three/examples/jsm/loaders/GLTFLoader.js","@pixiv/three-vrm"],f):(s=typeof globalThis<"u"?globalThis:s||self,f(s.StreamingCdnRtcAvatarVrm={},s.THREE,s.THREE,s.THREE_VRM))})(this,(function(s,f,j,h){"use strict";function x(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,o.get?o:{enumerable:!0,get:()=>e[t]})}}return n.default=e,Object.freeze(n)}const d=x(f);function M(e){const n=e.crownY-e.headY,t=n>.05&&n<1.5?n:.25,o=t*2.1,p=e.headY+t*.45-o*.08,i=o/2/Math.tan(28/2*(Math.PI/180));return{windowHeight:o,lookY:p,distance:i}}function V(e,n){return{render(t,o,l,p,i){if(e.applyAndRender(o,n),i){const r=i.radius*5.2;t.drawImage(e.canvas,i.x-r/2,i.y-r*.42,r,r)}else{const r=Math.min(l,p);t.drawImage(e.canvas,(l-r)/2,(p-r)/2,r,r)}},dispose(){e.dispose()}}}async function g(e,n=512){const t=document.createElement("canvas");t.width=n,t.height=n;const o=new d.WebGLRenderer({canvas:t,alpha:!0,antialias:!0});o.setClearColor(0,0);const l=new d.Scene;l.add(new d.AmbientLight(16777215,1.1));const p=new d.DirectionalLight(16777215,1.4);p.position.set(.5,1.2,1.5),l.add(p);const i=new d.PerspectiveCamera(28,1,.1,20),r=new j.GLTFLoader;r.register(a=>new h.VRMLoaderPlugin(a));const w=await r.parseAsync(e,""),c=w.userData.vrm;h.VRMUtils.removeUnnecessaryVertices(w.scene),h.VRMUtils.combineSkeletons(w.scene),h.VRMUtils.rotateVRM0(c),l.add(c.scene);const R=c.humanoid?.getNormalizedBoneNode("head"),y=new d.Vector3(0,1.35,0);R&&R.getWorldPosition(y),c.scene.updateWorldMatrix(!0,!0);const L=new d.Box3().setFromObject(c.scene),T=Number.isFinite(L.max.y)?L.max.y:y.y+.25,k=M({headY:y.y,crownY:T});i.position.set(0,k.lookY,k.distance),i.lookAt(0,k.lookY,0);const b=new d.Object3D;b.position.set(0,y.y,2),l.add(b),c.lookAt&&(c.lookAt.target=b);const Y=new d.Clock;return{canvas:t,applyAndRender(a,S){const v=S?.headGain??.9,u=c.expressionManager;if(u){const E=u.expressionMap??{},m=O=>!!E[O];m("blinkLeft")||m("blinkRight")?(u.setValue("blinkLeft",a.blinkLeft),u.setValue("blinkRight",a.blinkRight)):m("blink")&&u.setValue("blink",(a.blinkLeft+a.blinkRight)/2),m("aa")&&u.setValue("aa",Math.max(0,a.jawOpen)),m("happy")&&u.setValue("happy",Math.max(0,a.smile)),m("angry")&&u.setValue("angry",Math.max(0,-a.smile)*.6)}R&&R.rotation.set(-a.headPitch*v,a.headYaw*v,-a.headRoll*v),b.position.set(a.pupilX*1.2,y.y-a.pupilY*.8,2),c.update(Y.getDelta()),o.render(l,i)},dispose(){h.VRMUtils.deepDispose(c.scene),o.dispose()}}}async function A(e,n={}){const t=await g(e,n.size??640);return V(t,{headGain:n.headGain})}s.createVrmAvatarRenderer=A,s.createVrmStage=g,s.frameVrmBust=M,s.vrmAvatarRenderer=V,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streaming-cdn/rtc-web",
3
- "version": "1.3.25",
3
+ "version": "1.3.26",
4
4
  "type": "module",
5
5
  "main": "dist/rtc-web.umd.js",
6
6
  "module": "dist/rtc-web.es.js",