feat: Full Body Tracking (FBT) via MediaPipe Pose #39
No reviewers
Labels
No labels
architecture
bug
duplicate
enhancement
help wanted
invalid
performance
quality
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lavarius/ProjectOverlay!39
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/full-body-tracking"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #38
Summary
Adds MediaPipe Pose-based full body tracking, extending the existing face/hand UDP pipeline.
Python server (
PythonFaceCaptureServer)tracking_config.py: AddedENABLE_POSE_TRACKINGandPOSE_TRACKING_INTERVALtogglescombinerTracker_udp.py:PoseLandmarker,PoseLandmarkerOptions,PoseLandmarkerResultPOSE_LANDMARK_INDICESdict maps the 12 key joint indices (shoulders, elbows, wrists, hips, knees, ankles)callback_pose_result()callback stores world landmarksprocess_data()emitspose|world|{idx}|{x}|{y}|{z}lines for each key jointrun()creates PoseLandmarker from./models/pose_landmarker.taskpose_landmarker.detect_async()everyPOSE_TRACKING_INTERVALframesUnity (
Assets/_SRC/code/PipeServer/)FaceTrackingManager.csstatic event Action<Dictionary<int, Vector3>> OnPoseTrackingParsePoseTrackingData(): parsespose|world|idx|x|y|z, converts MediaPipe coords → Unity (negate Z)OnDetectionReceivedguard: pose + hand events now fire even when no face avatars are registeredBodyTrackingClient.cs(new)OnPoseTrackingtrackArms,trackLegs,trackHead,poseScale,smoothSpeedhipBoneanchorUpdate()TwoBoneIKConstraintweights on component enable/disableSetTrackingEnabled(bool)public APINext steps
BodyTrackingClienton each model inCharacter Inside.prefaband assign IK effector refs + hipBone- Removed: leg tracking, hipBone dependency, hipYOffset, mirrorX - Arms only: wrists (15/16) + elbows (13/14) as hints - Calibration replaces hip anchor: Press RecalibrateFBT (default key: ') while in idle/rest pose. Component records current MediaPipe wrist positions vs animated effector world positions and stores a persistent offset. charPos = mpPos * poseScale + calibOffset Re-calibrate any time tracking drifts. - Subscribes to InputSystemSpawner.OnPlayerInputReady and wires playerInput.actions["RecalibrateFBT"].performed -> Calibrate() - Before calibration, proxies pass-through the animated effectors so animation-based idle pose is preserved at startup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>- Python: send hand|{Left/Right}|{idx}|x|y|z using hand_world_landmarks (real metric coords, handedness label included) - FaceTrackingManager: add ParseHandWrists() extracting wrist (lm 0) per hand with correct coord flip (-x,y,-z); fires new static OnHandWristTracking(leftWrist, rightWrist) event - ParseHandTrackingData: updated to handle new format, backward- compatible with old hand|globalIdx format - BodyTrackingClient: fully rewritten to subscribe to OnHandWristTracking instead of OnPoseTracking; Calibrate() now uses hand data, no more 'no pose data received' error; elbows remain pass-through only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>- Remove incorrect Y-negation in ArmPoseDriver.OnPoseData. MediaPipe Pose WORLD landmarks are Y-UP (origin at hip midpoint, +Y toward head). FaceTrackingManager's (-x,y,-z) conversion is already correct. Negating Y again made pose-space Y-down while bone-space remained Y-up, causing cross products for the arm-plane normal to flip sign — producing inconsistent roll. - Replace hips.forward up-hint with arm-plane normal in both BuildAlignMatrices and LateUpdate: ArmPlaneNormal = Cross(shoulder→elbow, shoulder→wrist) This is always perpendicular to the arm axis (never degenerate for real arm poses), physically constrains elbow-bend direction, and is computed consistently from the same geometry in both spaces. - Add [DefaultExecutionOrder(15000)] to ArmPoseDriver and HandFingerDriver so writes happen after Animation Rigging RigBuilder (~10000-12000) and are not overwritten before rendering. - Add ArmPoseDiagnostic helper for runtime inspection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>- Add HandIKDriver.cs: IK-target-based arm tracking, runs at exec order 9000 (before Animation Rigging ~12000) so targets are set before IK solves. Drives Left/Right Paw + Elbow targets from MediaPipe pose landmarks. Inspector-assigned targets (no auto-find). Lerps back to rest on loss. Drives TwoBoneIKConstraint weight 0→1 on detection, 1→0 on loss. - Fix HandFingerDriver wrist rotation: - BuildWristAlign and ApplyWristDirect now use consistent backward dir convention - Add leftWristRotOffset / rightWristRotOffset (default Y=180) for residual flip - Rest rotation captured in Awake (localRotation, bind pose) — lerps back to that when hand data is lost, so offset doesn't stay frozen on screen - wristReturnSpeed controls lerp rate back to rest - Add HandTrackingToggle.cs: listens to ToggleHandTracking InputAction, flips trackingWeight (0↔1) on all HandFingerDrivers and trackingEnabled on all HandIKDrivers found in children. Auto-finds PlayerInput at runtime. - Rename Character Inside.prefab → Player.prefab, remove Saji.prefab - Add ToggleHandTracking action to LavaController.inputactions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>