Editor/HumanoidMocap/MocapTrackingStatus.cs
using System;
using System.Linq;
using Editor;
using Sandbox;
using HumanoidMocap.Mapping;
using HumanoidMocap.Motion;
namespace HumanoidMocap.Editor;
public sealed partial class RetargetWindow
{
Label _trackingStatus;
BakedPreview _trackingPreview;
int _trackingFrame=-1;
int _trackingLeft=-1,_trackingRight=-1;
void UpdateTrackingStatus()
{
if(!_trackingStatus.IsValid())return;
var preview=_bakedPreview;
if(preview is null||!HandCaptureRetargeter.Supports(preview.Source))
{_trackingStatus.Visible=false;_trackingPreview=null;_trackingFrame=-1;return;}
var frame=_mocapPreview.CurrentFrame;
if(ReferenceEquals(preview,_trackingPreview)&&frame==_trackingFrame)return;
var motion=preview.Source;
if(!ReferenceEquals(preview,_trackingPreview))
{
_trackingLeft=motion.Bones.FindIndex(b=>b.Role==BoneRole.HandL);
_trackingRight=motion.Bones.FindIndex(b=>b.Role==BoneRole.HandR);
}
_trackingPreview=preview;_trackingFrame=frame;
var start=motion.Frames[0].Time;var end=motion.Frames[^1].Time;
var time=Math.Min(start+frame/(double)preview.Clip.Fps,end);
var left=_trackingLeft<0?(JointEvidence?)null:MotionEvidence.At(motion,_trackingLeft,time);
var right=_trackingRight<0?(JointEvidence?)null:MotionEvidence.At(motion,_trackingRight,time);
string State(JointEvidence? evidence)=>evidence switch{
JointEvidence.Reconstructed=>"reconstructed",JointEvidence.InferredGap=>"inferred gap",
JointEvidence.GeneratedIk=>"IK estimate",JointEvidence.Authored=>"authored",
JointEvidence.Unobserved=>"not observed",_=>"not captured"};
var manual=preview.WristOffsets.Any(e=>WristPositionOffsets.Weight(e,time,start,end)>0);
var reach=preview.Clip.Mapping?.Notes.FirstOrDefault(n=>n.StartsWith(HandCaptureRetargeter.ReachWarningPrefix,StringComparison.Ordinal));
var missing=preview.Clip.Mapping?.Notes.FirstOrDefault(n=>n.StartsWith(HandCaptureRetargeter.MissingTargetTracksPrefix,StringComparison.Ordinal));
var text=$"Left wrist: {State(left)} · Right wrist: {State(right)}"+(manual?" · Manual correction":"")+(reach is not null?" · Clip: arm reach limited":"")+
(missing is not null?" · Target: unmapped joints":"");
if(_trackingStatus.Text!=text)
{
_trackingStatus.Text=text;
_trackingStatus.SetStyles($"color: {(reach is null&&missing is null&&left==JointEvidence.Reconstructed&&right==JointEvidence.Reconstructed?Theme.TextLight:Theme.Yellow).Hex};");
}
_trackingStatus.ToolTip=$"Evidence at animation time {time:F3} s. Reconstructed means a model prediction, not measured ground truth. "+
"Unobserved motion is not newly captured; a previous pose may be retained. Inferred gaps are interpolated. Hidden shoulders and elbows are estimated by IK. "+
"Manual and contact corrections do not turn missing observations into reconstructed motion."+(reach is not null?"\nClip-level check: "+reach:"")+
(missing is not null?"\nTarget compatibility: "+missing:"");
_trackingStatus.Visible=true;
}
}