Реалізація Body Tracking в AR-додатку
Body tracking — це відстеження позиції людини в реальному часі з прив'язкою 3D-контенту до суглобів тіла. Використовується у фітнес-додатках (аналіз техніки вправ), AR-примірці одягу, інтерактивних AR-іграх, де персонаж повторює рухи користувача. Технічно це складніше за face tracking: тіло далі від камери, гірше освітлене, перекривається одягом та фоном.
ARKit Body Tracking: архітектура
ARBodyTrackingConfiguration — iOS 13+, A12+. Відслідковує одну людину в кадрі (підтримка кількох тіл експериментальна та нестабільна).
Повертає ARBodyAnchor з skeleton типу ARSkeleton3D. Скелет містить 91 joint в ієрархії. Основні: root, hips, spine_1 через spine_7, left_shoulder_1_joint, left_arm_joint, left_forearm_joint, left_hand_joint, аналогічно права сторона, ноги, голова.
func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
guard let bodyAnchor = anchors.first as? ARBodyAnchor else { return }
let skeleton = bodyAnchor.skeleton
// Позиція правого запястя в мировых координатах
if let wristTransform = skeleton.modelTransform(for: .rightHand) {
let worldTransform = bodyAnchor.transform * wristTransform
// Прив'язати об'єкт до запястя
}
}
modelTransform(for:) повертає трансформацію відносно root (таза). Для мирових координат множимо на bodyAnchor.transform.
Обмеження та практика
Дистанція: впевнений трекінг — від 1.5 до 5 метрів. Менш 1 метра тіло виходить за кадр. Більше 5 метрів — нестабільність суглобів, особливо кистей та ступнів.
Часткова видимість: коли частина тіла за кадром, ARKit екстраполює позицію "невидимих" суглобів за кінематичною моделлю. Точність екстраполяції нормальна для туловища та ніг, гірше для рук.
Швидкість руху: при швидких рухах (стрибки, боксерські удари) трекінг рук запізнюється на 2–4 кадри. Для fitness coaching це проблема — вимірювання швидкості удару буде занижено.
Одна людина: якщо у кадрі двоє — ARKit трекує одну (звичайно першу виявлену). ARBodyAnchor — тільки один. Для multi-person tracking потрібен сторонній ML.
Прив'язка 3D-персонажа до скелету
Готова USDZ-сцена з rigged персонажем. Rig повинен відповідати ARKit joint hierarchy — 91 joint з тими ж іменами (left_arm_joint, right_hand_joint і т.д.). Blender: створюємо armature з ARKit-іменами суглобів, експортуємо у USDZ.
RealityKit BodyTrackedEntity — спеціальний клас, який автоматично застосовує ARKit skeleton transforms до сумісного USDZ:
var character: BodyTrackedEntity?
func loadCharacter() async {
character = try? await Entity.load(named: "robot.usdz") as? BodyTrackedEntity
let bodyAnchor = AnchorEntity(.body)
bodyAnchor.addChild(character!)
arView.scene.addAnchor(bodyAnchor)
}
Якщо імена joints у USDZ не збігаються з ARKit — персонаж "розлітається". Перевірка через Reality Composer Pro: Joint mapping inspector.
MediaPipe Pose для Android та крос-платформи
ARCore не надає body tracking. Для Android — MediaPipe Pose Landmarker:
- 33 ключові точки (BlazePose GHUM)
- Працює на RGB-камері, без depth sensor
-
PoseLandmarker.detect()→PoseLandmarkerResultз 3D-координатами у нормалізованому просторі
Для прив'язки 3D-контенту в ARCore: конвертуємо 2D-координати точок + глибину (якщо є LiDAR/ToF) у AR world coordinates через Frame.hitTest() або depth API.
Точність MediaPipe гірше ARKit: ~5–10 см помилка позиції суглоба vs ~1–3 см у ARKit на пристроях з Neural Engine. Для фітнес-аналітики — достатньо. Для точного скелетного риггінгу 3D-персонажа — помітна різниця.
Аналіз рухів для фітнесу
Кут у суглобі через dot product двох векторів:
func jointAngle(joint1: simd_float3, vertex: simd_float3, joint2: simd_float3) -> Float {
let v1 = normalize(joint1 - vertex)
let v2 = normalize(joint2 - vertex)
return acos(dot(v1, v2)) * (180 / .pi)
}
Кут колена при приседанні: jointAngle(hip, knee, ankle). Правильний діапазон — 80–110°. Якщо < 60° — користувач приседає занадто глибоко. Це основа для real-time формо-коучингу.
Сроки
Базовий body tracking з прив'язкою 3D-об'єкта до суглоба — 1–2 тижні. Риггінг 3D-персонажа під ARKit skeleton + інтеграція — 3–4 тижні. Фітнес-аналітика з аналізом кутів суглобів та лічильником повторень — 4–6 тижнів. Android MediaPipe-версія — додатково 2–3 тижні. Вартість розраховується індивідуально.







