Editor/HumanoidMocap/PreviewWidget.Props.cs
using System;
using System.Linq;
using HumanoidMocap.Maths;
using HumanoidMocap.Motion;
using Sandbox;
namespace HumanoidMocap.Editor;
public sealed partial class PreviewWidget
{
public PropContactMotion CaptureProps { get; set; }
public CapturePlacement PropPlacement { get; set; }
public int PropBoneOverlayCount { get; private set; }
public string ContactTargetKey { get; set; }
public int FingerContactOverlayCount { get; private set; }
void DrawPropBones()
{
PropBoneOverlayCount=0;
FingerContactOverlayCount=0;
if(CaptureProps is null||_clip is null||CaptureProps.Objects.Count==0)return;
var time=Math.Min(CaptureProps.StartTime+CurrentFrame/(double)_clip.Fps,CaptureProps.EndTime);
UpdateGizmoInputs(false);
using(Gizmo.Scope("HumanoidMocap.PropBones"))
{
Gizmo.Transform=Transform.Zero;Gizmo.Draw.IgnoreDepth=true;Gizmo.Draw.LineThickness=2;
Gizmo.Draw.Color=new Color(.25f,.85f,1f,1f);
foreach(var prop in CaptureProps.Objects)
{
if(!CaptureProps.TrySample(prop.Id,time,out var world,out var available))continue;
for(var b=0;b<world.Length;b++)
{
if(!available[b])continue;
var point=RigWorldToEngine(PropPlacement.Transform(world[b])).Position;
Gizmo.Draw.SolidSphere(point,.18f,8,8);
var parent=prop.Bones[b].Parent;
if(parent>=0)Gizmo.Draw.Line(RigWorldToEngine(PropPlacement.Transform(world[parent])).Position,point);
PropBoneOverlayCount++;
}
}
foreach(var contact in CaptureProps.Contacts.Where(c=>c.Review!=ContactReview.Disabled&&time>=c.Start&&time<=c.End))
{
if(!CaptureProps.TrySample(contact.Object,time,out var propWorld,out var available))continue;
var prop=CaptureProps.Objects.Single(p=>p.Id==contact.Object);
var part=string.IsNullOrEmpty(contact.ObjectBone)?0:prop.Bones.FindIndex(b=>b.Name==contact.ObjectBone);
if(part<0||!available[part])continue;
foreach(var target in contact.FingerTargets.Where(t=>t.TargetKey==ContactTargetKey))
{
if(_rig.BoneForRole(target.Role) is not int bone)continue;
var finger=RigWorldToEngine(XForm.Compose(_worldScratch[bone],new(MotionDocument.V(target.LocalPoint)*PropPlacement.Units,System.Numerics.Quaternion.Identity))).Position;
var goal=RigWorldToEngine(PropPlacement.Transform(XForm.Compose(propWorld[part],new(FingerContactCorrection.TargetAt(contact,target,time),System.Numerics.Quaternion.Identity)))).Position;
Gizmo.Draw.Color=contact.Review==ContactReview.Confirmed?new Color(.3f,1f,.4f):new Color(1f,.85f,.2f);
Gizmo.Draw.Line(finger,goal);Gizmo.Draw.SolidSphere(goal,.14f,8,8);
Gizmo.Draw.Color=new Color(1f,.35f,.8f);Gizmo.Draw.SolidSphere(finger,.12f,8,8);FingerContactOverlayCount++;
}
}
}
}
}