@ssafy-mhk/e-ver 1.0.2 → 1.0.4

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 (69) hide show
  1. package/README.md +183 -114
  2. package/dist/api/EverClient.d.ts +12 -1
  3. package/dist/api/EverClient.test.d.ts +1 -0
  4. package/dist/avatar/VRMCompat.d.ts +8 -0
  5. package/dist/avatar/avatarLoader.d.ts +12 -0
  6. package/dist/avatar/humanoidBindings.d.ts +7 -0
  7. package/dist/bodyPreset/presetSelection.d.ts +31 -0
  8. package/dist/components/CameraView.d.ts +5 -0
  9. package/dist/components/EverCanvas.d.ts +2 -0
  10. package/dist/components/EverFittingScene.d.ts +18 -0
  11. package/dist/components/EverFittingScene.test.d.ts +1 -0
  12. package/dist/components/EverProvider.d.ts +0 -8
  13. package/dist/components/EverTrackedGarment.d.ts +15 -0
  14. package/dist/components/TrackedGarmentPoseDriver.d.ts +13 -0
  15. package/dist/components/WebcamPlaneBackground.d.ts +7 -0
  16. package/dist/components/ever-context.d.ts +9 -0
  17. package/dist/compositing/videoCover.d.ts +14 -0
  18. package/dist/fitting/bodyFirstFitting.d.ts +14 -0
  19. package/dist/fitting/bodyFirstFitting.test.d.ts +1 -0
  20. package/dist/garment/constants.d.ts +1 -0
  21. package/dist/garment/fitMotion.d.ts +18 -0
  22. package/dist/garment/garmentFitProfile.d.ts +24 -0
  23. package/dist/garment/poseApplication.d.ts +18 -0
  24. package/dist/garment/trackedGarmentMotion.d.ts +32 -0
  25. package/dist/garment/trackedModelTransform.d.ts +40 -0
  26. package/dist/hooks/useAvatarVariant.d.ts +12 -0
  27. package/dist/hooks/useBodyMeasurer.d.ts +13 -4
  28. package/dist/hooks/useBodyMeasurer.test.d.ts +1 -0
  29. package/dist/hooks/useBodyPresetSelection.d.ts +3 -0
  30. package/dist/hooks/useEverFitting.d.ts +51 -0
  31. package/dist/hooks/useEverFitting.test.d.ts +1 -0
  32. package/dist/hooks/useEverGeneration.d.ts +4 -5
  33. package/dist/hooks/useEverGeneration.test.d.ts +1 -0
  34. package/dist/hooks/useMeasurement.d.ts +19 -0
  35. package/dist/hooks/usePoseMapper.d.ts +2 -1
  36. package/dist/hooks/usePoseTracker.d.ts +24 -6
  37. package/dist/hooks/usePoseTracker.test.d.ts +1 -0
  38. package/dist/hooks/useWebcam.d.ts +19 -0
  39. package/dist/hooks/useWebcam.test.d.ts +1 -0
  40. package/dist/index.d.ts +45 -0
  41. package/dist/index.es.js +3119 -40588
  42. package/dist/index.umd.js +1 -4415
  43. package/dist/measurement/garmentScaler.d.ts +19 -0
  44. package/dist/measurement/scaleCalculator.d.ts +5 -0
  45. package/dist/measurement/scaleCalculator.test.d.ts +1 -0
  46. package/dist/measurement/silhouetteExtractor.d.ts +3 -0
  47. package/dist/measurement/sizeRecommender.d.ts +2 -0
  48. package/dist/pose/boneMapping.d.ts +14 -0
  49. package/dist/pose/coordinateTransform.d.ts +9 -0
  50. package/dist/pose/facingDetector.d.ts +35 -0
  51. package/dist/pose/interpolation.d.ts +16 -0
  52. package/dist/pose/landmarkPoseSolver.d.ts +9 -0
  53. package/dist/pose/landmarkerFactory.d.ts +13 -0
  54. package/dist/pose/poseSolver.d.ts +2 -0
  55. package/dist/pose/segmentation.d.ts +9 -0
  56. package/dist/pose/smoothing.d.ts +12 -0
  57. package/dist/pose/yawDirectionStabilizer.d.ts +20 -0
  58. package/dist/pose/yawFreezeController.d.ts +11 -0
  59. package/dist/publicApi.test.d.ts +1 -0
  60. package/dist/store/useEverStore.d.ts +10 -5
  61. package/dist/tracking/personLock.d.ts +39 -0
  62. package/dist/tracking/trackingStability.d.ts +6 -0
  63. package/dist/tracking/trackingState.d.ts +18 -0
  64. package/dist/types/bodyPreset.d.ts +65 -0
  65. package/dist/types/fitting.d.ts +15 -0
  66. package/dist/types/measurement.d.ts +42 -0
  67. package/dist/types/pose.d.ts +81 -0
  68. package/dist/types/tracking.d.ts +13 -0
  69. package/package.json +11 -6
@@ -0,0 +1,19 @@
1
+ import type { BodyMeasurements, GarmentScaleParams } from "../types/measurement";
2
+ export interface GarmentSpec {
3
+ refShoulderWidthCm: number;
4
+ refHeightCm: number;
5
+ refArmLengthCm: number;
6
+ refChestCircumferenceCm: number;
7
+ refWaistCircumferenceCm: number;
8
+ refHipWidthCm: number;
9
+ refTorsoLengthCm: number;
10
+ shoulderEaseCm: number;
11
+ chestEaseCm: number;
12
+ waistEaseCm: number;
13
+ hipEaseCm: number;
14
+ torsoEaseCm: number;
15
+ armEaseCm: number;
16
+ fitEaseScale: number;
17
+ }
18
+ export declare const DEFAULT_GARMENT_SPEC: GarmentSpec;
19
+ export declare function computeGarmentScale(measurements: BodyMeasurements, spec?: GarmentSpec): GarmentScaleParams;
@@ -0,0 +1,5 @@
1
+ import type { BodyMeasurements, SilhouetteWidths } from "../types/measurement";
2
+ import { type PoseLandmarkLike } from "../types/pose";
3
+ export declare function computeScale(landmarks: PoseLandmarkLike[], referenceHeightCm: number, imageHeight?: number): number;
4
+ export declare function computeBmiCorrectionFactor(bmi: number): number;
5
+ export declare function measureBody(landmarks: PoseLandmarkLike[], referenceHeightCm: number, weightKg?: number | null, silhouetteWidths?: SilhouetteWidths | null, imageWidth?: number, imageHeight?: number): BodyMeasurements;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { SilhouetteWidths } from "../types/measurement";
2
+ import { type PoseLandmarkLike } from "../types/pose";
3
+ export declare function extractSilhouetteWidths(maskData: Float32Array, maskWidth: number, maskHeight: number, landmarks: PoseLandmarkLike[]): SilhouetteWidths | null;
@@ -0,0 +1,2 @@
1
+ import type { BodyMeasurements, SizeRecommendation } from "../types/measurement";
2
+ export declare function recommendSize(measurements: BodyMeasurements): SizeRecommendation | null;
@@ -0,0 +1,14 @@
1
+ import type { JointRotation, PoseRig } from "../types/pose";
2
+ type RotationScale = number | Partial<Record<keyof JointRotation, number>>;
3
+ interface BoneMappingEntry {
4
+ rigKey: keyof PoseRig | null;
5
+ rotationScale?: RotationScale;
6
+ rotationLimits?: Partial<Record<keyof JointRotation, {
7
+ min: number;
8
+ max: number;
9
+ }>>;
10
+ }
11
+ export declare const BONE_MAPPING: Record<string, BoneMappingEntry>;
12
+ export declare function normalizeBoneName(boneName: string): string;
13
+ export declare function getBoneRotation(boneName: string, poseRig: PoseRig): JointRotation | null;
14
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { NormalizedLandmark } from "@mediapipe/tasks-vision";
2
+ import * as THREE from "three";
3
+ export interface CoordinateTransformOptions {
4
+ mirrorX?: boolean;
5
+ sourceWidth?: number;
6
+ sourceHeight?: number;
7
+ target?: THREE.Vector3;
8
+ }
9
+ export declare function landmarkToThreePosition(landmark: NormalizedLandmark, viewportWidth: number, viewportHeight: number, mirrorXOrOptions?: boolean | CoordinateTransformOptions, target?: THREE.Vector3): THREE.Vector3;
@@ -0,0 +1,35 @@
1
+ import type { NormalizedLandmark } from "@mediapipe/tasks-vision";
2
+ import { type YawDirection } from "./yawDirectionStabilizer";
3
+ export type FacingZone = "front" | "side" | "back";
4
+ export interface FacingState {
5
+ zone: FacingZone;
6
+ rawZone: FacingZone;
7
+ isFrontFacing: boolean;
8
+ pitchClamped: boolean;
9
+ bodyYaw: number;
10
+ bodyPitch: number;
11
+ rawYawDirection: YawDirection;
12
+ yawDirection: YawDirection;
13
+ committedYawDirection: YawDirection;
14
+ }
15
+ export interface FacingSignals {
16
+ shoulderOrder: boolean;
17
+ noseVisible: boolean;
18
+ earSymmetry: boolean;
19
+ }
20
+ export declare function extractFacingSignals(landmarks: NormalizedLandmark[] | null): FacingSignals;
21
+ export declare function isRawFrontFacing(signals: FacingSignals): boolean;
22
+ export declare class FacingDetector {
23
+ private _zone;
24
+ private _consecutiveCount;
25
+ private _lastRawZone;
26
+ private _2dFrontCount;
27
+ private _2dBackCount;
28
+ private _2dIsFront;
29
+ private _yawDirectionStabilizer;
30
+ update(landmarks: NormalizedLandmark[] | null, bodyYaw?: number, bodyPitch?: number): FacingState;
31
+ reset(): void;
32
+ private _resolve2dFallback;
33
+ private _applyHysteresis;
34
+ private _getTransitionThreshold;
35
+ }
@@ -0,0 +1,16 @@
1
+ import type { SilhouetteWidths } from "../types/measurement";
2
+ import type { PoseLandmarkLike, PoseRig } from "../types/pose";
3
+ export interface PoseFrameSnapshot {
4
+ landmarks: PoseLandmarkLike[] | null;
5
+ worldLandmarks: PoseLandmarkLike[] | null;
6
+ poseRig: PoseRig | null;
7
+ confidence: number;
8
+ isTracking: boolean;
9
+ silhouetteWidths: SilhouetteWidths | null;
10
+ }
11
+ export declare function lerpValue(start: number, end: number, alpha: number): number;
12
+ export declare function interpolateLandmarks(previous: PoseLandmarkLike[] | null, next: PoseLandmarkLike[] | null, alpha: number): PoseLandmarkLike[] | null;
13
+ export declare function interpolatePoseRig(previous: PoseRig | null, next: PoseRig | null, alpha: number): PoseRig | null;
14
+ export declare function interpolateSilhouetteWidths(previous: SilhouetteWidths | null, next: SilhouetteWidths | null, alpha: number): SilhouetteWidths | null;
15
+ export declare function createInitialPoseSnapshot(): PoseFrameSnapshot;
16
+ export declare function interpolatePoseSnapshot(previous: PoseFrameSnapshot | null, next: PoseFrameSnapshot, alpha: number): PoseFrameSnapshot;
@@ -0,0 +1,9 @@
1
+ import * as THREE from "three";
2
+ import { type PoseLandmarkLike } from "../types/pose";
3
+ export type LandmarkCoordinateSpace = "normalized" | "world";
4
+ export type LandmarkSelector = number | readonly [number, number];
5
+ export declare function computeLandmarkSegmentDirection(from: LandmarkSelector, to: LandmarkSelector, landmarks: PoseLandmarkLike[], target: THREE.Vector3, coordinateSpace?: LandmarkCoordinateSpace): boolean;
6
+ export declare function computeBoneDirectionFromLandmarks(boneName: string, landmarks: PoseLandmarkLike[], target: THREE.Vector3, coordinateSpace?: LandmarkCoordinateSpace): boolean;
7
+ export declare function getBoneLandmarkInfluence(boneName: string): number | undefined;
8
+ export declare function computeBoneRotationFromLandmarks(boneName: string, landmarks: PoseLandmarkLike[], target: THREE.Quaternion, coordinateSpace?: LandmarkCoordinateSpace): boolean;
9
+ export declare function hasLandmarkMapping(boneName: string): boolean;
@@ -0,0 +1,13 @@
1
+ import { PoseLandmarker } from "@mediapipe/tasks-vision";
2
+ export declare const MEDIAPIPE_TASKS_VISION_VERSION = "0.10.32";
3
+ export declare const WASM_FILES_URL = "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.32/wasm";
4
+ export declare const POSE_DETECTION_INTERVAL = 2;
5
+ export declare const DEFAULT_NUM_POSES = 3;
6
+ export declare const INTERPOLATION_ALPHA = 0.5;
7
+ export declare const MODEL_ASSET_PATHS: {
8
+ readonly lite: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/latest/pose_landmarker_lite.task";
9
+ readonly full: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_full/float16/latest/pose_landmarker_full.task";
10
+ readonly heavy: "https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_heavy/float16/latest/pose_landmarker_heavy.task";
11
+ };
12
+ export type ModelComplexity = keyof typeof MODEL_ASSET_PATHS;
13
+ export declare function createPoseLandmarker(modelAssetPath: string, minDetectionConfidence: number, minTrackingConfidence: number, outputSegmentationMasks: boolean, numPoses?: number): Promise<PoseLandmarker>;
@@ -0,0 +1,2 @@
1
+ import type { PoseLandmarkLike, PoseRig } from "../types/pose";
2
+ export declare function solvePose(landmarks: PoseLandmarkLike[], worldLandmarks?: PoseLandmarkLike[] | null): PoseRig | null;
@@ -0,0 +1,9 @@
1
+ import type { SilhouetteWidths } from "../types/measurement";
2
+ export interface SegmentationMaskLike {
3
+ width: number;
4
+ height: number;
5
+ getAsFloat32Array: () => Float32Array;
6
+ }
7
+ export declare function getSegmentationMaskData(mask: unknown): SegmentationMaskLike | null;
8
+ export declare function closeSegmentationMasks(masks: readonly unknown[] | undefined): void;
9
+ export declare function scaleSilhouetteWidths(silhouetteWidths: SilhouetteWidths, frameWidth: number, maskWidth: number): SilhouetteWidths;
@@ -0,0 +1,12 @@
1
+ import { type JointRotation, type PoseLandmarkLike, type PoseRig, type SmoothingConfig } from "../types/pose";
2
+ export declare function normalizeLandmark(landmark: PoseLandmarkLike): PoseLandmarkLike;
3
+ export declare function normalizeLandmarks(landmarks: PoseLandmarkLike[]): PoseLandmarkLike[];
4
+ export declare class LandmarkSmoother {
5
+ private prev;
6
+ private readonly config;
7
+ constructor(config?: SmoothingConfig);
8
+ smooth(current: PoseLandmarkLike[]): PoseLandmarkLike[];
9
+ reset(): void;
10
+ }
11
+ export declare function lerpRotation(prev: JointRotation, next: JointRotation, alpha: number): JointRotation;
12
+ export declare function smoothPoseRig(prev: PoseRig | null, next: PoseRig, alpha?: number): PoseRig;
@@ -0,0 +1,20 @@
1
+ export type YawDirection = "positive" | "negative" | "unknown";
2
+ export interface StabilizedYawState {
3
+ rawYawDirection: YawDirection;
4
+ yawDirection: YawDirection;
5
+ committedYawDirection: YawDirection;
6
+ pendingYawDirection: YawDirection;
7
+ pendingCount: number;
8
+ stableYaw: number;
9
+ }
10
+ type FacingZoneLike = "front" | "side" | "back";
11
+ export declare class YawDirectionStabilizer {
12
+ private _committedYawDirection;
13
+ private _pendingYawDirection;
14
+ private _pendingCount;
15
+ update(zone: FacingZoneLike, yaw: number): StabilizedYawState;
16
+ reset(): void;
17
+ private _buildState;
18
+ private _clearPending;
19
+ }
20
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { FacingZone } from "./facingDetector";
2
+ export interface YawFreezeState {
3
+ isFrozen: boolean;
4
+ frozenYaw: number | null;
5
+ }
6
+ export declare class YawFreezeController {
7
+ private _isFrozen;
8
+ private _frozenYaw;
9
+ update(zone: FacingZone, yaw: number, _displayYaw: number): YawFreezeState;
10
+ reset(): void;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,17 +1,22 @@
1
+ export interface PoseLandmark {
2
+ x: number;
3
+ y: number;
4
+ z: number;
5
+ visibility?: number;
6
+ presence?: number;
7
+ }
1
8
  export interface EverState {
2
9
  isWebcamActive: boolean;
3
- activeAvatarUrl: string | null;
4
10
  activeGarmentUrl: string | null;
5
- landmarks: any | null;
6
- worldLandmarks: any | null;
11
+ landmarks: PoseLandmark[] | null;
12
+ worldLandmarks: PoseLandmark[] | null;
7
13
  fitResult: {
8
14
  type: "slim" | "regular" | "oversize" | null;
9
15
  suitability: number;
10
16
  } | null;
11
17
  setWebcamActive: (active: boolean) => void;
12
- setActiveAvatarUrl: (url: string | null) => void;
13
18
  setActiveGarmentUrl: (url: string | null) => void;
14
- setLandmarks: (landmarks: any, worldLandmarks: any) => void;
19
+ setLandmarks: (landmarks: PoseLandmark[] | null, worldLandmarks: PoseLandmark[] | null) => void;
15
20
  setFitResult: (result: EverState["fitResult"]) => void;
16
21
  }
17
22
  export declare const useEverStore: import("zustand").UseBoundStore<import("zustand").StoreApi<EverState>>;
@@ -0,0 +1,39 @@
1
+ import type { VisibleNormalizedRegion } from "../compositing/videoCover";
2
+ import type { PoseLandmarkLike } from "../types/pose";
3
+ export interface NormalizedRect {
4
+ x: number;
5
+ y: number;
6
+ w: number;
7
+ h: number;
8
+ }
9
+ export interface PoseCandidate {
10
+ poseIndex: number;
11
+ personId: string;
12
+ landmarks: PoseLandmarkLike[];
13
+ worldLandmarks: PoseLandmarkLike[] | null;
14
+ bounds: NormalizedRect;
15
+ expandedBounds: NormalizedRect;
16
+ meanVisibility: number;
17
+ area: number;
18
+ }
19
+ export interface LockedPoseCandidate {
20
+ poseIndex: number;
21
+ personId: string;
22
+ bounds: NormalizedRect;
23
+ expandedBounds: NormalizedRect;
24
+ }
25
+ interface SelectLockedPoseCandidateOptions {
26
+ previousCandidate: LockedPoseCandidate | null;
27
+ allowRelock?: boolean;
28
+ minIouToKeep?: number;
29
+ }
30
+ export declare function clampNormalizedRect(rect: NormalizedRect | null): NormalizedRect | null;
31
+ export declare function computeLandmarkBoundsNormalized(landmarks: PoseLandmarkLike[]): NormalizedRect | null;
32
+ export declare function expandNormalizedRect(rect: NormalizedRect | null, expandRatio?: number): NormalizedRect | null;
33
+ export declare function calcRectIoU(a: NormalizedRect | null, b: NormalizedRect | null): number;
34
+ export declare function createPoseCandidates(landmarkSets: PoseLandmarkLike[][], worldLandmarkSets?: PoseLandmarkLike[][]): PoseCandidate[];
35
+ export declare function selectLockedPoseCandidate(candidates: PoseCandidate[], { previousCandidate, allowRelock, minIouToKeep, }: SelectLockedPoseCandidateOptions): PoseCandidate | null;
36
+ export declare function isCandidateInVisibleRegion(candidate: PoseCandidate, visibleRegion: VisibleNormalizedRegion | null): boolean;
37
+ export declare function filterCandidatesByVisibleRegion(candidates: PoseCandidate[], visibleRegion: VisibleNormalizedRegion | null): PoseCandidate[];
38
+ export declare function toLockedPoseCandidate(candidate: PoseCandidate | null): LockedPoseCandidate | null;
39
+ export {};
@@ -0,0 +1,6 @@
1
+ import type { PoseFrameSnapshot } from "../pose/interpolation";
2
+ import { type TrackingRuntimeState } from "../types/tracking";
3
+ export declare const TRACKING_SNAPSHOT_HOLD_MS = 180;
4
+ export declare function shouldHoldTrackingSnapshot(lastTrackedAt: number | null, now: number, holdMs?: number): boolean;
5
+ export declare function createHeldTrackingSnapshot(snapshot: PoseFrameSnapshot | null): PoseFrameSnapshot | null;
6
+ export declare function createTrackingLostRuntimeState(detectedPersonCount: number, updatedAt: number, lockedPersonId?: string | null): TrackingRuntimeState;
@@ -0,0 +1,18 @@
1
+ import { type TrackingQuality, type TrackingRuntimeState } from "../types/tracking";
2
+ interface CreateTrackingQualityOptions {
3
+ detectedPersonCount: number;
4
+ isTracking: boolean;
5
+ lockedPersonId?: string | null;
6
+ meanVisibility?: number | null;
7
+ frameWidth?: number;
8
+ frameHeight?: number;
9
+ updatedAt?: number;
10
+ }
11
+ interface CreateTrackingRuntimeStateOptions extends CreateTrackingQualityOptions {
12
+ lockedPersonId?: string | null;
13
+ }
14
+ export declare function createIdleTrackingQuality(updatedAt?: number | null): TrackingQuality;
15
+ export declare function createTrackingQuality({ detectedPersonCount, isTracking, lockedPersonId, meanVisibility, frameWidth, frameHeight, updatedAt, }: CreateTrackingQualityOptions): TrackingQuality;
16
+ export declare function createInitialTrackingRuntimeState(): TrackingRuntimeState;
17
+ export declare function createTrackingRuntimeState({ detectedPersonCount, isTracking, lockedPersonId, meanVisibility, frameWidth, frameHeight, updatedAt, }: CreateTrackingRuntimeStateOptions): TrackingRuntimeState;
18
+ export {};
@@ -0,0 +1,65 @@
1
+ import type { BodyMeasurements } from "./measurement";
2
+ export type BodyPresetGender = "male" | "female";
3
+ export type BodyPresetSelectionSource = "match" | "default" | "fallback";
4
+ export interface BodyPresetTaxonomy {
5
+ sizeBand: string;
6
+ upperBodySilhouette: string;
7
+ torsoOrPelvisProfile: string;
8
+ }
9
+ export interface BodyPresetMetrics {
10
+ heightCm: number | null;
11
+ chestCm: number | null;
12
+ waistCm: number | null;
13
+ hipCm: number | null;
14
+ shoulderWidthCm: number | null;
15
+ armLengthCm: number | null;
16
+ inseamCm: number | null;
17
+ torsoLengthCm: number | null;
18
+ neckToHipCm: number | null;
19
+ }
20
+ export interface BodyPresetSelection {
21
+ id: string | null;
22
+ presetId: string;
23
+ label: string;
24
+ modelUrl: string;
25
+ gender: BodyPresetGender;
26
+ source: BodyPresetSelectionSource;
27
+ taxonomy: BodyPresetTaxonomy;
28
+ metrics: BodyPresetMetrics;
29
+ }
30
+ export interface BodyPresetSelectionState {
31
+ selection: BodyPresetSelection;
32
+ loading: boolean;
33
+ error: string | null;
34
+ }
35
+ export interface BodyPresetSummary {
36
+ id: string;
37
+ presetId: string;
38
+ baseGender: BodyPresetGender;
39
+ sizeBand: string;
40
+ upperBodySilhouette: string;
41
+ torsoOrPelvisProfile: string;
42
+ modelUrl: string;
43
+ heightCm: number | null;
44
+ chestCm: number | null;
45
+ waistCm: number | null;
46
+ hipCm: number | null;
47
+ shoulderWidthCm: number | null;
48
+ armLengthCm: number | null;
49
+ inseamCm: number | null;
50
+ torsoLengthCm: number | null;
51
+ neckToHipCm: number | null;
52
+ }
53
+ export interface BodyPresetMatchRequest {
54
+ gender: BodyPresetGender;
55
+ height_cm?: number;
56
+ chest_cm?: number;
57
+ waist_cm?: number;
58
+ shoulder_width_cm?: number;
59
+ }
60
+ export interface UseBodyPresetSelectionOptions {
61
+ gender?: BodyPresetGender;
62
+ renderMode?: "rigged_avatar" | "preset-native";
63
+ legacyPresetId?: string;
64
+ }
65
+ export type { BodyMeasurements };
@@ -0,0 +1,15 @@
1
+ import type { GarmentScaleParams } from "./measurement";
2
+ export type FitType = "slim" | "regular" | "oversize";
3
+ export type PostureAdjust = "neutral" | "rounded_shoulder" | "sway_back";
4
+ export interface BodyMorphResult {
5
+ torsoScale: number;
6
+ chestScale: number;
7
+ waistScale: number;
8
+ hipScale: number;
9
+ shoulderAdjust: number;
10
+ postureAdjust: PostureAdjust;
11
+ }
12
+ export interface BodyFirstFittingResult {
13
+ scale: GarmentScaleParams;
14
+ morph: BodyMorphResult | null;
15
+ }
@@ -0,0 +1,42 @@
1
+ export type MeasurementMethod = "silhouette_depth" | "silhouette_bmi" | "keypoint" | "user_input";
2
+ export type AccuracyGrade = "premium" | "standard" | "estimate";
3
+ export interface BodyMeasurements {
4
+ heightCm: number;
5
+ shoulderWidthCm: number | null;
6
+ chestCircumferenceCm: number | null;
7
+ waistCircumferenceCm: number | null;
8
+ hipWidthCm: number | null;
9
+ armLengthCm: number | null;
10
+ legLengthCm: number | null;
11
+ torsoLengthCm: number | null;
12
+ accuracyGrade?: AccuracyGrade | null;
13
+ confidenceScore?: number | null;
14
+ measurementMethod?: MeasurementMethod | null;
15
+ measuredAt?: string | null;
16
+ }
17
+ export interface SilhouetteWidths {
18
+ shoulderWidthPx: number;
19
+ chestWidthPx: number;
20
+ waistWidthPx: number;
21
+ hipWidthPx: number;
22
+ }
23
+ export interface GarmentScaleParams {
24
+ scaleX: number;
25
+ scaleY: number;
26
+ scaleZ: number;
27
+ sleeveScale: number;
28
+ fitEaseScale: number;
29
+ }
30
+ export type ClothingSize = "S" | "M" | "L" | "XL" | "2XL";
31
+ export interface SizeRecommendation {
32
+ size: ClothingSize;
33
+ confidence: number;
34
+ fitDescription: string;
35
+ }
36
+ export interface MeasurementConfig {
37
+ referenceHeightCm: number;
38
+ weightKg: number | null;
39
+ stableFrameCount: number;
40
+ motionThreshold: number;
41
+ }
42
+ export declare const DEFAULT_MEASUREMENT_CONFIG: MeasurementConfig;
@@ -0,0 +1,81 @@
1
+ export interface PoseLandmarkLike {
2
+ x: number;
3
+ y: number;
4
+ z: number;
5
+ visibility?: number;
6
+ presence?: number;
7
+ }
8
+ export declare const LANDMARK: {
9
+ readonly NOSE: 0;
10
+ readonly LEFT_EYE_INNER: 1;
11
+ readonly LEFT_EYE: 2;
12
+ readonly LEFT_EYE_OUTER: 3;
13
+ readonly RIGHT_EYE_INNER: 4;
14
+ readonly RIGHT_EYE: 5;
15
+ readonly RIGHT_EYE_OUTER: 6;
16
+ readonly LEFT_EAR: 7;
17
+ readonly RIGHT_EAR: 8;
18
+ readonly MOUTH_LEFT: 9;
19
+ readonly MOUTH_RIGHT: 10;
20
+ readonly LEFT_SHOULDER: 11;
21
+ readonly RIGHT_SHOULDER: 12;
22
+ readonly LEFT_ELBOW: 13;
23
+ readonly RIGHT_ELBOW: 14;
24
+ readonly LEFT_WRIST: 15;
25
+ readonly RIGHT_WRIST: 16;
26
+ readonly LEFT_PINKY: 17;
27
+ readonly RIGHT_PINKY: 18;
28
+ readonly LEFT_INDEX: 19;
29
+ readonly RIGHT_INDEX: 20;
30
+ readonly LEFT_THUMB: 21;
31
+ readonly RIGHT_THUMB: 22;
32
+ readonly LEFT_HIP: 23;
33
+ readonly RIGHT_HIP: 24;
34
+ readonly LEFT_KNEE: 25;
35
+ readonly RIGHT_KNEE: 26;
36
+ readonly LEFT_ANKLE: 27;
37
+ readonly RIGHT_ANKLE: 28;
38
+ readonly LEFT_HEEL: 29;
39
+ readonly RIGHT_HEEL: 30;
40
+ readonly LEFT_FOOT_INDEX: 31;
41
+ readonly RIGHT_FOOT_INDEX: 32;
42
+ };
43
+ export interface JointRotation {
44
+ x: number;
45
+ y: number;
46
+ z: number;
47
+ }
48
+ export interface PoseRig {
49
+ hips: {
50
+ position: {
51
+ x: number;
52
+ y: number;
53
+ z: number;
54
+ };
55
+ rotation: JointRotation;
56
+ };
57
+ spine: JointRotation;
58
+ chest: JointRotation;
59
+ leftUpperArm: JointRotation;
60
+ leftLowerArm: JointRotation;
61
+ rightUpperArm: JointRotation;
62
+ rightLowerArm: JointRotation;
63
+ leftUpperLeg?: JointRotation;
64
+ leftLowerLeg?: JointRotation;
65
+ rightUpperLeg?: JointRotation;
66
+ rightLowerLeg?: JointRotation;
67
+ }
68
+ export interface PoseState {
69
+ landmarks: PoseLandmarkLike[] | null;
70
+ worldLandmarks: PoseLandmarkLike[] | null;
71
+ poseRig: PoseRig | null;
72
+ confidence: number;
73
+ fps: number;
74
+ isTracking: boolean;
75
+ }
76
+ export interface SmoothingConfig {
77
+ positionAlpha: number;
78
+ rotationAlpha: number;
79
+ visibilityThreshold: number;
80
+ }
81
+ export declare const DEFAULT_SMOOTHING: SmoothingConfig;
@@ -0,0 +1,13 @@
1
+ export type TrackingQualityLevel = "idle" | "good" | "degraded" | "blocked";
2
+ export type TrackingQualityReason = "no_person_detected" | "pose_not_locked" | "multi_person_detected" | "low_visibility" | "occluded" | "backlight_detected" | "distance_out_of_range" | "resolution_too_low" | "tracking_lost";
3
+ export interface TrackingQuality {
4
+ level: TrackingQualityLevel;
5
+ reasons: TrackingQualityReason[];
6
+ updatedAt: number | null;
7
+ }
8
+ export interface TrackingRuntimeState {
9
+ detectedPersonCount: number;
10
+ lockedPersonId: string | null;
11
+ trackingQuality: TrackingQuality;
12
+ }
13
+ export declare const DEFAULT_LOCKED_PERSON_ID = "pose-0";
package/package.json CHANGED
@@ -5,9 +5,7 @@
5
5
  "@react-three/drei": "^10.7.7",
6
6
  "@react-three/fiber": "^9.5.0",
7
7
  "@types/three": "^0.183.1",
8
- "axios": "^1.13.6",
9
- "three": "^0.183.2",
10
- "zustand": "^5.0.12"
8
+ "axios": "^1.13.6"
11
9
  },
12
10
  "devDependencies": {
13
11
  "@eslint/js": "^9.39.4",
@@ -44,15 +42,22 @@
44
42
  "name": "@ssafy-mhk/e-ver",
45
43
  "peerDependencies": {
46
44
  "react": ">=16.8.0",
47
- "react-dom": ">=16.8.0"
45
+ "react-dom": ">=16.8.0",
46
+ "three": ">=0.150.0",
47
+ "@react-three/fiber": ">=8.0.0",
48
+ "@react-three/drei": ">=9.0.0",
49
+ "@mediapipe/tasks-vision": ">=0.10.0",
50
+ "zustand": ">=4.0.0"
48
51
  },
49
52
  "scripts": {
50
53
  "build": "vite build && tsc -p tsconfig.app.json",
51
54
  "dev": "vite",
52
55
  "lint": "eslint .",
53
- "preview": "vite preview"
56
+ "preview": "vite preview",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest"
54
59
  },
55
60
  "type": "module",
56
61
  "types": "./dist/index.d.ts",
57
- "version": "1.0.2"
62
+ "version": "1.0.4"
58
63
  }