@ssafy-mhk/e-ver 1.0.0 → 1.0.2
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 +170 -5
- package/dist/api/EverClient.d.ts +168 -0
- package/dist/components/AvatarModel.d.ts +11 -0
- package/dist/components/CameraView.d.ts +10 -0
- package/dist/components/EverCanvas.d.ts +10 -0
- package/dist/components/EverProvider.d.ts +17 -0
- package/dist/components/GarmentModel.d.ts +10 -0
- package/dist/hooks/useBodyMeasurer.d.ts +11 -0
- package/dist/hooks/useEverGeneration.d.ts +17 -0
- package/dist/hooks/usePoseMapper.d.ts +7 -0
- package/dist/hooks/usePoseMapper.test.d.ts +1 -0
- package/dist/hooks/usePoseTracker.d.ts +7 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.es.js +40791 -3
- package/dist/index.umd.js +4415 -1
- package/dist/store/useEverStore.d.ts +17 -0
- package/dist/store/useEverStore.test.d.ts +1 -0
- package/dist/test/setup.d.ts +1 -0
- package/package.json +34 -28
package/README.md
CHANGED
|
@@ -1,10 +1,175 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@ssafy-mhk/e-ver` - Virtual Fitting React SDK 👗👕
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
S14P21M104 가상 피팅(WebAR) 프로젝트를 위한 공식 프론트엔드 React SDK입니다.
|
|
4
|
+
복잡한 Three.js 카메라 및 조명 설정, MediaPipe AI 바디 트래킹 연동, SkinnedMesh 기반 의류 렌더링 로직을 추상화하여, **단순한 React 컴포넌트와 Hook**으로 증강현실(AR) 가상 피팅 기능을 빠르게 구현할 수 있도록 지원합니다.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## 개발 스택 (Technology Stack)
|
|
7
|
+
|
|
8
|
+
- **Framework**: React / Next.js 호환
|
|
9
|
+
- **3D & AR Rendering**: Three.js, React Three Fiber (R3F), Drei, three-vrm
|
|
10
|
+
- **AI Tracking**: MediaPipe Pose Landmarker (Lite)
|
|
11
|
+
- **State Management**: Zustand
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🛠 설치 방법 (Installation)
|
|
16
|
+
|
|
17
|
+
이 패키지는 사내 또는 외부 NPM에 직접 배포되기 전 로컬 저장소를 통한 심볼릭 링크(Symbolic Link) 방식으로 연결하거나 파일 디렉토리를 참조하여 사용할 수 있습니다.
|
|
18
|
+
|
|
19
|
+
### 로컬 프로젝트에서 참조하여 설치할 경우:
|
|
20
|
+
|
|
21
|
+
여러분의 Next.js 프로젝트 최상위 폴더(`frontend`)에서 아래 명령어를 실행하세요.
|
|
6
22
|
|
|
7
23
|
```bash
|
|
8
|
-
pnpm
|
|
9
|
-
pnpm
|
|
24
|
+
# pnpm 사용 시
|
|
25
|
+
pnpm add @ssafy-mhk/e-ver
|
|
26
|
+
|
|
27
|
+
# 또는 패키지 매니저에 따라
|
|
28
|
+
npm install @ssafy-mhk/e-ver
|
|
29
|
+
yarn add @ssafy-mhk/e-ver
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
_(의존성 설치가 잘 되었는지 꼭 `package.json` 코드를 확인하세요.)_
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 🚀 코어로직 한눈에 보기 (SDK 핵심 요소)
|
|
37
|
+
|
|
38
|
+
SDK는 크게 **State(상태 관리)**, **Renderer(렌더링 UI)**, **Tracker(추적/측정 Hook)** 이렇게 3가지 핵심 축으로 구성됩니다.
|
|
39
|
+
|
|
40
|
+
| 분류 | 모듈명 | 역할 |
|
|
41
|
+
| ------------ | ----------------- | ------------------------------------------------------------------------------------ |
|
|
42
|
+
| **State** | `useEverStore` | 웹캠 활성화 여부, 렌더링 중인 옷/아바타 주소, 최종 핏 결과(체형 측정) 관리 |
|
|
43
|
+
| **Renderer** | `EverCanvas` | AR/3D 환경에 최적화된 조명과 카메라 세팅을 내장한 R3F 캔버스 래퍼 |
|
|
44
|
+
| **Renderer** | `AvatarModel` | 사용자의 AI 기반 생성 3D 아바타(GLB)를 로딩하고, 뼈대(Bone) 구조를 추출 |
|
|
45
|
+
| **Renderer** | `GarmentModel` | 사용자가 선택한 옷(GLB)을 로딩하고, 옷의 SkinnedMesh를 대상 아바타에 입힘 |
|
|
46
|
+
| **Tracker** | `usePoseTracker` | 브라우저 내에서 MediaPipe를 가동시켜 실시간 30-60Hz 웹캠 추적 |
|
|
47
|
+
| **Tracker** | `usePoseMapper` | 웹캠에서 얻은 2D/3D 점(Landmarks)을 필수 13본(Bone)의 회전값(Quaternion)으로 변환 |
|
|
48
|
+
| **Tracker** | `useBodyMeasurer` | AR 카메라 상에서 사용자 실루엣 기반 사이즈(어깨, 가슴, 허리)를 연산하여 옷의 핏 평가 |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 📖 사용 가이드 (Usage Guide)
|
|
53
|
+
|
|
54
|
+
아래는 Next.js(App Router) 환경에서 가상 피팅 서비스를 구축하는 기본 예제 코드입니다.
|
|
55
|
+
|
|
56
|
+
### Step 1. Zustand로 글로벌 상태 세팅하기
|
|
57
|
+
|
|
58
|
+
우선, 애플리케이션 외부 버튼 조작을 위해 스토어를 호출할 수 있습니다.
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// app/fitting/page.tsx
|
|
62
|
+
"use client";
|
|
63
|
+
|
|
64
|
+
import { useEverStore } from "@ssafy-mhk/e-ver";
|
|
65
|
+
|
|
66
|
+
export default function FittingControls() {
|
|
67
|
+
const { setWebcamActive, setActiveGarmentUrl, fitResult } = useEverStore();
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<div className="absolute top-4 left-4 z-10 flex flex-col gap-2">
|
|
71
|
+
<button onClick={() => setWebcamActive(true)}>웹캠 가동 시작 🎥</button>
|
|
72
|
+
<button onClick={() => setActiveGarmentUrl("/path/to/clothes.glb")}>
|
|
73
|
+
새로운 옷 입어보기 👕
|
|
74
|
+
</button>
|
|
75
|
+
|
|
76
|
+
{fitResult && (
|
|
77
|
+
<div className="bg-white/80 p-2 rounded">
|
|
78
|
+
핏 타입: {fitResult.type} (적합도 {fitResult.suitability}%)
|
|
79
|
+
</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Step 2. 3D AR 캔버스 및 모델 구축하기
|
|
87
|
+
|
|
88
|
+
SDK에서 제공하는 `EverCanvas`, `AvatarModel`, `GarmentModel`을 활용하여 화면을 그립니다.
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
// components/VirtualFittingScene.tsx
|
|
92
|
+
"use client";
|
|
93
|
+
|
|
94
|
+
import { useState } from "react";
|
|
95
|
+
import {
|
|
96
|
+
EverCanvas,
|
|
97
|
+
AvatarModel,
|
|
98
|
+
GarmentModel,
|
|
99
|
+
useEverStore,
|
|
100
|
+
} from "@ssafy-mhk/e-ver";
|
|
101
|
+
|
|
102
|
+
export default function VirtualFittingScene() {
|
|
103
|
+
const [avatarBones, setAvatarBones] = useState<Record<string, THREE.Bone>>();
|
|
104
|
+
const { activeGarmentUrl } = useEverStore();
|
|
105
|
+
|
|
106
|
+
// 내 계정의 3D 아바타 파일 경로
|
|
107
|
+
const AVATAR_URL = "/models/my-avatar.glb";
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div className="w-full h-screen bg-transparent relative">
|
|
111
|
+
{/* 1. 기본 AR 조명이 세팅된 캔버스 호출 */}
|
|
112
|
+
<EverCanvas showEnvironment={true}>
|
|
113
|
+
{/* 2. 사용자의 베이스 아바타 불러오기 */}
|
|
114
|
+
<AvatarModel
|
|
115
|
+
url={AVATAR_URL}
|
|
116
|
+
onBonesReady={(bones) => setAvatarBones(bones)}
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
{/* 3. 활성화된 옷이 있다면 아바타 위에 덧입히기 */}
|
|
120
|
+
{activeGarmentUrl && avatarBones && (
|
|
121
|
+
<GarmentModel
|
|
122
|
+
url={activeGarmentUrl}
|
|
123
|
+
targetAvatarBones={avatarBones}
|
|
124
|
+
/>
|
|
125
|
+
)}
|
|
126
|
+
</EverCanvas>
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Step 3. AI 바디 트래킹 연동하기
|
|
133
|
+
|
|
134
|
+
웹캠 화면과 R3F 화면을 겹쳐주려면 `<video>` 태그를 `usePoseTracker`에 넘겨 연결해 주어야 합니다.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
// components/ArCameraView.tsx
|
|
138
|
+
"use client";
|
|
139
|
+
|
|
140
|
+
import { useRef } from "react";
|
|
141
|
+
import { usePoseTracker, useEverStore } from "@ssafy-mhk/e-ver";
|
|
142
|
+
|
|
143
|
+
export default function ArCameraView() {
|
|
144
|
+
const videoRef = useRef<HTMLVideoElement>(null);
|
|
145
|
+
|
|
146
|
+
// SDK 내부의 로직을 통해 실시간으로 프레임을 MediaPipe에 전송
|
|
147
|
+
const { isTrackerReady } = usePoseTracker(videoRef);
|
|
148
|
+
const { isWebcamActive } = useEverStore();
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div className="absolute inset-0 z-0">
|
|
152
|
+
<video
|
|
153
|
+
ref={videoRef}
|
|
154
|
+
autoPlay
|
|
155
|
+
playsInline
|
|
156
|
+
muted
|
|
157
|
+
className="w-full h-full object-cover"
|
|
158
|
+
style={{ display: isWebcamActive ? "block" : "none" }}
|
|
159
|
+
/>
|
|
160
|
+
{/* Tracker가 로딩 중일 때 로딩 오버레이 표시 가능 */}
|
|
161
|
+
{!isTrackerReady && isWebcamActive && <p>AI 모델 로딩 중...</p>}
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
10
165
|
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 🙋♂️ Q&A (추가 기능 문의)
|
|
170
|
+
|
|
171
|
+
**Q. 옷 핏 평가는 어떻게 동작하나요?**
|
|
172
|
+
-> 내부에 구축된 `useBodyMeasurer` 훅이 약 1초 단위(1Hz)로 캔버스의 실루엣을 통해 [어깨, 가슴, 허리] 사이즈를 분석하여 `useEverStore`의 `fitResult`에 자동 업데이트합니다.
|
|
173
|
+
|
|
174
|
+
**Q. 물리 엔진(Rapier.js)이 적용되어 있나요?**
|
|
175
|
+
-> 현재 MVP 스코프에서 무거운 런타임 물리 물리엔진은 제외되었으며, 대신 **SkinnedMesh 본 바인딩(P0)**과 **Normal Map 애니메이션(P1)**을 통하여 주름과 디테일을 시뮬레이션합니다.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export type GarmentCategory = "top" | "bottom" | "dress" | "outer" | "accessory";
|
|
2
|
+
export type GarmentAssetStatus = "uploaded" | "trellis_pending" | "trellis_complete" | "rigging_pending" | "rigging_in_progress" | "rigging_complete" | "rigging_failed" | "rigging_fallback" | "ready";
|
|
3
|
+
export interface BodyPreset {
|
|
4
|
+
id: string;
|
|
5
|
+
preset_id: string;
|
|
6
|
+
base_gender: string;
|
|
7
|
+
size_band: string;
|
|
8
|
+
upper_body_silhouette: string;
|
|
9
|
+
torso_or_pelvis_profile: string;
|
|
10
|
+
model_url: string | null;
|
|
11
|
+
height_cm: number | null;
|
|
12
|
+
chest_cm: number | null;
|
|
13
|
+
waist_cm: number | null;
|
|
14
|
+
hip_cm: number | null;
|
|
15
|
+
shoulder_width_cm: number | null;
|
|
16
|
+
arm_length_cm: number | null;
|
|
17
|
+
inseam_cm: number | null;
|
|
18
|
+
torso_length_cm: number | null;
|
|
19
|
+
neck_to_hip_cm: number | null;
|
|
20
|
+
}
|
|
21
|
+
export interface BodyPresetMatchRequest {
|
|
22
|
+
gender: string;
|
|
23
|
+
height_cm?: number;
|
|
24
|
+
chest_cm?: number;
|
|
25
|
+
waist_cm?: number;
|
|
26
|
+
hip_cm?: number;
|
|
27
|
+
shoulder_width_cm?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface GarmentData {
|
|
30
|
+
name: string;
|
|
31
|
+
category: GarmentCategory;
|
|
32
|
+
brand_id?: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
material?: string;
|
|
35
|
+
price?: number | string;
|
|
36
|
+
thumbnail_url?: string;
|
|
37
|
+
model_url?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface GarmentImage {
|
|
40
|
+
id: string;
|
|
41
|
+
image_url: string;
|
|
42
|
+
image_type: string;
|
|
43
|
+
sort_order: number;
|
|
44
|
+
is_primary: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface GarmentSize {
|
|
47
|
+
id: string;
|
|
48
|
+
garment_id: string;
|
|
49
|
+
size: string;
|
|
50
|
+
fit_type: string;
|
|
51
|
+
shoulder_width_cm: number | null;
|
|
52
|
+
chest_cm: number | null;
|
|
53
|
+
total_length_cm: number | null;
|
|
54
|
+
waist_cm: number | null;
|
|
55
|
+
hip_cm: number | null;
|
|
56
|
+
sleeve_length_cm: number | null;
|
|
57
|
+
inseam_cm: number | null;
|
|
58
|
+
rise_cm: number | null;
|
|
59
|
+
thigh_cm: number | null;
|
|
60
|
+
hem_cm: number | null;
|
|
61
|
+
created_at: string;
|
|
62
|
+
updated_at: string;
|
|
63
|
+
}
|
|
64
|
+
export interface GarmentVariant {
|
|
65
|
+
id: string;
|
|
66
|
+
color: string | null;
|
|
67
|
+
pattern: string | null;
|
|
68
|
+
is_default: boolean;
|
|
69
|
+
model_url: string | null;
|
|
70
|
+
size: string | null;
|
|
71
|
+
fit_type: string | null;
|
|
72
|
+
shoulder_width_cm: number | null;
|
|
73
|
+
chest_cm: number | null;
|
|
74
|
+
total_length_cm: number | null;
|
|
75
|
+
waist_cm: number | null;
|
|
76
|
+
hip_cm: number | null;
|
|
77
|
+
sleeve_length_cm: number | null;
|
|
78
|
+
inseam_cm: number | null;
|
|
79
|
+
rise_cm: number | null;
|
|
80
|
+
thigh_cm: number | null;
|
|
81
|
+
hem_cm: number | null;
|
|
82
|
+
}
|
|
83
|
+
export interface GarmentSummary {
|
|
84
|
+
id: string;
|
|
85
|
+
brand_id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
category: string;
|
|
88
|
+
occlusion_hint: string | null;
|
|
89
|
+
description: string | null;
|
|
90
|
+
material: string | null;
|
|
91
|
+
price: number | string | null;
|
|
92
|
+
external_url: string | null;
|
|
93
|
+
thumbnail_url: string | null;
|
|
94
|
+
model_url: string | null;
|
|
95
|
+
asset_status: GarmentAssetStatus;
|
|
96
|
+
is_active: boolean;
|
|
97
|
+
created_at: string;
|
|
98
|
+
updated_at: string;
|
|
99
|
+
}
|
|
100
|
+
export interface GarmentDetail extends GarmentSummary {
|
|
101
|
+
brand: {
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
logo_url: string | null;
|
|
105
|
+
website_url: string | null;
|
|
106
|
+
} | null;
|
|
107
|
+
images: GarmentImage[];
|
|
108
|
+
sizes: GarmentSize[];
|
|
109
|
+
variants: GarmentVariant[];
|
|
110
|
+
}
|
|
111
|
+
export interface GarmentListResponse {
|
|
112
|
+
items: GarmentSummary[];
|
|
113
|
+
total: number;
|
|
114
|
+
page: number;
|
|
115
|
+
size: number;
|
|
116
|
+
}
|
|
117
|
+
export interface GarmentPipelineStatus {
|
|
118
|
+
garment_id: string;
|
|
119
|
+
asset_status: GarmentAssetStatus;
|
|
120
|
+
progress: number;
|
|
121
|
+
message: string;
|
|
122
|
+
}
|
|
123
|
+
export interface Generate3DResponse {
|
|
124
|
+
garment_id: string;
|
|
125
|
+
asset_status: GarmentAssetStatus;
|
|
126
|
+
status_url: string;
|
|
127
|
+
message: string;
|
|
128
|
+
include_measurements: boolean;
|
|
129
|
+
target_fit_types: string[];
|
|
130
|
+
}
|
|
131
|
+
export interface ListGarmentsParams {
|
|
132
|
+
category?: string;
|
|
133
|
+
search?: string;
|
|
134
|
+
page?: number;
|
|
135
|
+
size?: number;
|
|
136
|
+
}
|
|
137
|
+
export interface WaitForGarmentModelOptions {
|
|
138
|
+
intervalMs?: number;
|
|
139
|
+
timeoutMs?: number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* EverClient provides methods to interact with the e-ver backend API.
|
|
143
|
+
*/
|
|
144
|
+
export declare class EverClient {
|
|
145
|
+
private readonly baseUrl;
|
|
146
|
+
private readonly apiOrigin;
|
|
147
|
+
constructor(baseUrl?: string);
|
|
148
|
+
resolveAssetUrl(assetUrl: string | null): string | null;
|
|
149
|
+
listBodyPresets(gender?: string): Promise<BodyPreset[]>;
|
|
150
|
+
matchBodyPreset(body: BodyPresetMatchRequest): Promise<BodyPreset>;
|
|
151
|
+
listGarments(params?: ListGarmentsParams): Promise<GarmentListResponse>;
|
|
152
|
+
getGarment(garmentId: string): Promise<GarmentDetail>;
|
|
153
|
+
getPipelineStatus(garmentId: string): Promise<GarmentPipelineStatus>;
|
|
154
|
+
createGarment(data: GarmentData): Promise<GarmentSummary>;
|
|
155
|
+
uploadGarmentImage(garmentId: string, photo: Blob, type: "front" | "back"): Promise<GarmentImage[]>;
|
|
156
|
+
generateGarment3D(garmentId: string, options?: {
|
|
157
|
+
include_measurements?: boolean;
|
|
158
|
+
target_fit_types?: string[];
|
|
159
|
+
}): Promise<Generate3DResponse>;
|
|
160
|
+
waitForGarmentModel(garmentId: string, options?: WaitForGarmentModelOptions): Promise<GarmentDetail>;
|
|
161
|
+
pickGarmentModelUrl(garment: Pick<GarmentDetail, "model_url" | "variants">): string | null;
|
|
162
|
+
private normalizeBodyPreset;
|
|
163
|
+
private normalizeGarmentSummary;
|
|
164
|
+
private normalizeGarmentDetail;
|
|
165
|
+
private request;
|
|
166
|
+
private buildUrl;
|
|
167
|
+
private getResponseErrorMessage;
|
|
168
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
export interface AvatarModelProps {
|
|
4
|
+
url: string | null;
|
|
5
|
+
onBonesReady?: (bones: Record<string, THREE.Bone>) => void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Loads and renders the user's 3D avatar (GLB/VRM).
|
|
9
|
+
* Automatically registers bone references to the EverProvider for the pose mapping pipeline.
|
|
10
|
+
*/
|
|
11
|
+
export declare const AvatarModel: React.FC<AvatarModelProps>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface CameraViewProps {
|
|
3
|
+
className?: string;
|
|
4
|
+
style?: React.CSSProperties;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* CameraView handles the rendering of the user's webcam feed.
|
|
8
|
+
* It automatically registers the video element to the EverProvider for tracking.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CameraView: React.FC<CameraViewProps>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface EverCanvasProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
showEnvironment?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A wrapper around R3F <Canvas> specifically configured for optimal
|
|
8
|
+
* 3D garment rendering and AR visualization.
|
|
9
|
+
*/
|
|
10
|
+
export declare const EverCanvas: React.FC<EverCanvasProps>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
export interface EverContextType {
|
|
4
|
+
videoRef: React.RefObject<HTMLVideoElement | null>;
|
|
5
|
+
avatarBones: Record<string, THREE.Bone> | null;
|
|
6
|
+
setAvatarBones: (bones: Record<string, THREE.Bone> | null) => void;
|
|
7
|
+
isProviderReady: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const useEver: () => EverContextType;
|
|
10
|
+
export interface EverProviderProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* EverProvider coordinates the shared state between tracking and rendering.
|
|
15
|
+
* It manages the video reference for MediaPipe and the bone mappings for 3D models.
|
|
16
|
+
*/
|
|
17
|
+
export declare const EverProvider: React.FC<EverProviderProps>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import * as THREE from "three";
|
|
3
|
+
export interface GarmentModelProps {
|
|
4
|
+
url: string | null;
|
|
5
|
+
targetAvatarBones?: Record<string, THREE.Bone>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Loads the clothing GLB and binds its SkinnedMeshes to the target avatar's bones.
|
|
9
|
+
*/
|
|
10
|
+
export declare const GarmentModel: React.FC<GarmentModelProps>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type BodyPresetMatchRequest, type GarmentData } from "../api/EverClient";
|
|
2
|
+
export type GenerationStatus = "idle" | "uploading" | "processing" | "ready" | "error";
|
|
3
|
+
/**
|
|
4
|
+
* Coordinates backend-backed model acquisition for the SDK demo flows.
|
|
5
|
+
*
|
|
6
|
+
* `generateAvatar` keeps the legacy call signature for compatibility, but the
|
|
7
|
+
* backend currently exposes body preset matching rather than photo-based avatar
|
|
8
|
+
* synthesis. Blob input therefore resolves to a default preset match.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useEverGeneration(baseUrl?: string): {
|
|
11
|
+
status: GenerationStatus;
|
|
12
|
+
resultUrl: string | null;
|
|
13
|
+
error: string | null;
|
|
14
|
+
generateAvatar: (input?: Blob | BodyPresetMatchRequest) => Promise<string>;
|
|
15
|
+
createGarment: (data: GarmentData, frontImage: Blob, backImage?: Blob, dimensions?: Record<string, unknown>) => Promise<string>;
|
|
16
|
+
reset: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initializes MediaPipe Pose Landmarker (Lite).
|
|
3
|
+
* Connects to the user's webcam feed and outputs real-time skeletal landmarks to the store.
|
|
4
|
+
*/
|
|
5
|
+
export declare const usePoseTracker: (videoRef: React.RefObject<HTMLVideoElement | null>) => {
|
|
6
|
+
isTrackerReady: boolean;
|
|
7
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from "./store/useEverStore";
|
|
2
|
+
export * from "./components/EverProvider";
|
|
3
|
+
export * from "./components/EverCanvas";
|
|
4
|
+
export * from "./components/CameraView";
|
|
5
|
+
export * from "./components/AvatarModel";
|
|
6
|
+
export * from "./components/GarmentModel";
|
|
7
|
+
export * from "./hooks/usePoseTracker";
|
|
8
|
+
export * from "./hooks/usePoseMapper";
|
|
9
|
+
export * from "./hooks/useBodyMeasurer";
|
|
10
|
+
export * from "./api/EverClient";
|
|
11
|
+
export * from "./hooks/useEverGeneration";
|