P2~P7 리노컷 캐스트 원화·리그와 세션 활성화
- 추천 원화(P2 b·P3 v2b·P4 v2b·P5 v2a·P6 v2b·P7 v2b)로 얼굴 없는 기본형·몸 원본 codex 편집, 정렬·정규화 후 공통 파이프라인 실행 - 게시 자산 apps/web/public/avatar/v3/p2~p7, 리그 rigs/p2Rig~p7Rig - 세션 레지스트리 P1~P7 전원 활성, Lab은 생성된 리그 자동 수집 - P3·P6 기본 눈 감김을 줄여 중립 렌더를 원화 눈매에 맞춤 - 표정 E2E를 v3 렌더러 기대로 갱신(검사 의도 유지)
This commit is contained in:
parent
98577cf4ae
commit
ded312acdc
258 changed files with 18463 additions and 32 deletions
|
|
@ -53,26 +53,35 @@ test.describe("avatar expression lab", () => {
|
|||
);
|
||||
await expect(panel.locator('[data-expression-card="true"]')).toHaveCount(28);
|
||||
|
||||
const cardRenderers = panel.locator(
|
||||
'.axl__card .vg-avatar [data-avatar-renderer="linocut"]',
|
||||
);
|
||||
await expect(cardRenderers).toHaveCount(28);
|
||||
await expect
|
||||
.poll(
|
||||
async () =>
|
||||
cardRenderers.evaluateAll(
|
||||
(els) => els.filter((el) => el.getAttribute("data-load-state") === "ready").length,
|
||||
),
|
||||
{ timeout: 20_000 },
|
||||
)
|
||||
.toBe(28);
|
||||
|
||||
const sectionMetrics = await panel.evaluate((el) => {
|
||||
const avatars = Array.from(el.querySelectorAll<HTMLElement>(".axl__card .vg-avatar"));
|
||||
const invalid = avatars
|
||||
.map((avatar) => {
|
||||
const neck = avatar.querySelector<SVGGraphicsElement>('[data-avatar-neck="true"]');
|
||||
const svg = avatar.querySelector("svg");
|
||||
const renderer = avatar.querySelector<HTMLElement>('[data-avatar-renderer="linocut"]');
|
||||
const svg = avatar.querySelector(".linocut-avatar");
|
||||
return {
|
||||
affect: avatar.getAttribute("data-affect"),
|
||||
primitives: avatar.querySelectorAll("svg path, svg ellipse, svg circle, svg line, svg rect")
|
||||
.length,
|
||||
neckBox: neck?.getBoundingClientRect().toJSON(),
|
||||
loadState: renderer?.getAttribute("data-load-state"),
|
||||
svgBox: svg?.getBoundingClientRect().toJSON(),
|
||||
};
|
||||
})
|
||||
.filter((item) => {
|
||||
return (
|
||||
item.primitives < 12 ||
|
||||
!item.neckBox ||
|
||||
item.neckBox.width <= 8 ||
|
||||
item.neckBox.height <= 14 ||
|
||||
item.loadState !== "ready" ||
|
||||
!item.svgBox ||
|
||||
item.svgBox.width <= 0 ||
|
||||
item.svgBox.height <= 0
|
||||
|
|
|
|||
|
|
@ -197,6 +197,10 @@ test.describe("persona avatar expression rig", () => {
|
|||
await expect(avatar).toBeVisible();
|
||||
await expect(avatar).toHaveAttribute("data-affect", persona.expectedExpression);
|
||||
|
||||
const v3 = avatar.locator('[data-avatar-renderer="linocut"]');
|
||||
await expect(v3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 });
|
||||
await expect(v3.locator(".linocut-avatar")).toBeVisible();
|
||||
|
||||
const metrics = await avatar.evaluate((el) => ({
|
||||
expressionCount: Number(el.getAttribute("data-expression-count")),
|
||||
live2dSchema: el.getAttribute("data-live2d-schema"),
|
||||
|
|
@ -207,10 +211,7 @@ test.describe("persona avatar expression rig", () => {
|
|||
live2dExpressionCount: Number(el.getAttribute("data-live2d-expression-count")),
|
||||
renderMode: el.getAttribute("data-render-mode"),
|
||||
rasterCount: el.querySelectorAll(".vg-raster").length,
|
||||
primitiveCount: el.querySelectorAll("svg path, svg ellipse, svg circle, svg line, svg rect")
|
||||
.length,
|
||||
neckBox: el.querySelector<SVGGraphicsElement>('[data-avatar-neck="true"]')?.getBoundingClientRect().toJSON(),
|
||||
svgBox: el.querySelector("svg")?.getBoundingClientRect().toJSON(),
|
||||
v3Box: el.querySelector(".linocut-avatar")?.getBoundingClientRect().toJSON(),
|
||||
}));
|
||||
expect(metrics.expressionCount, `${persona.code} expression count`).toBeGreaterThanOrEqual(20);
|
||||
expect(metrics.live2dSchema, `${persona.code} Live2D schema`).toBe("vignette.live2d.v1");
|
||||
|
|
@ -225,10 +226,8 @@ test.describe("persona avatar expression rig", () => {
|
|||
expect(metrics.live2dExpressionCount, `${persona.code} Live2D expressions`).toBeGreaterThanOrEqual(20);
|
||||
expect(metrics.renderMode, `${persona.code} render mode`).toBe("svg");
|
||||
expect(metrics.rasterCount, `${persona.code} raster rig should be disabled`).toBe(0);
|
||||
expect(metrics.primitiveCount, `${persona.code} SVG primitives`).toBeGreaterThan(10);
|
||||
expect(metrics.neckBox?.width, `${persona.code} SVG neck`).toBeGreaterThan(0);
|
||||
expect(metrics.svgBox?.width, `${persona.code} SVG rig`).toBeGreaterThan(0);
|
||||
expect(metrics.svgBox?.height, `${persona.code} SVG rig`).toBeGreaterThan(0);
|
||||
expect(metrics.v3Box?.width, `${persona.code} linocut SVG`).toBeGreaterThan(0);
|
||||
expect(metrics.v3Box?.height, `${persona.code} linocut SVG`).toBeGreaterThan(0);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -261,9 +260,10 @@ test.describe("persona avatar expression rig", () => {
|
|||
|
||||
const activeAvatar = page.locator(".sx-page--active .vg-avatar").first();
|
||||
await expect(activeAvatar).toBeVisible();
|
||||
await expect(activeAvatar).toHaveAttribute("data-render-mode", "svg");
|
||||
const activeV3 = activeAvatar.locator('[data-avatar-renderer="linocut"]');
|
||||
await expect(activeV3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 });
|
||||
await expect(activeV3.locator(".linocut-avatar")).toBeVisible();
|
||||
await expect(activeAvatar.locator(".vg-raster")).toHaveCount(0);
|
||||
await expect(activeAvatar.locator(".vg-avatar__svg")).toBeVisible();
|
||||
await expect(activeAvatar).toHaveAttribute("data-expression-count", "28");
|
||||
await expect(activeAvatar).toHaveAttribute("data-live2d-expression-count", "28");
|
||||
await expect(activeAvatar).toHaveAttribute("data-live2d-model", "vignette-p4-live2d");
|
||||
|
|
@ -316,9 +316,10 @@ test.describe("persona avatar expression rig", () => {
|
|||
await page.getByRole("button", { name: "회기 시작" }).click();
|
||||
await expect(page.locator(".sx-page--active")).toBeVisible();
|
||||
const activeAvatar = page.locator(".sx-page--active .vg-avatar").first();
|
||||
await expect(activeAvatar).toHaveAttribute("data-render-mode", "svg");
|
||||
const activeV3 = activeAvatar.locator('[data-avatar-renderer="linocut"]');
|
||||
await expect(activeV3).toHaveAttribute("data-load-state", "ready", { timeout: 15_000 });
|
||||
await expect(activeV3.locator(".linocut-avatar")).toBeVisible();
|
||||
await expect(activeAvatar.locator(".vg-raster")).toHaveCount(0);
|
||||
await expect(activeAvatar.locator(".vg-avatar__svg")).toBeVisible();
|
||||
await expect(activeAvatar).toHaveAttribute("data-live2d-motion", "anxious");
|
||||
|
||||
await setLearnerUtterance(page, "조금 안정된 것 같아요.");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue