s&box Package Code Search

Search C# source code, UI razor templates, shaders, and configs across s&box packages.

Showing code results for query: * (609 total matches found)
notpointless.chomnr_humanoid_mocap_x / FlowSampler.cs
Game library
// C# adaptation of FlowHMR's x1 Euler sampling. See THIRD_PARTY_NOTICES.md.
using System;
using System.Threading;

namespace HumanoidMocapX;

/// <summary>Predicts the clean 491-channel motion latent at a normalized time in [0,1).
/// Writes every output element; failures and cancellation propagate.</summary>
public delegate void FlowPrediction(ReadOnlySpan<float> state, float time, Span<float> output, CancellationToken cancellation);

/// <summary>The released Base and Latest models use twenty Euler steps and x1 prediction.</summary>
public static class FlowSampler
{
    public const int Channels = 491;
    public const int Steps = 20;

    /// <summary>Replaces caller-supplied initial noise with sampled motion using a reusable
    /// prediction buffer. Rejects invalid shapes and non-finite predictions. A failed or
    /// cancelled run may leave state partially advanced; it must not be exported.</summary>
    public static void Sample(float[] state, float[] prediction, FlowPrediction predict,
        CancellationToken cancellation = default)
    {
        ArgumentNullException.ThrowIfNull(state);
        ArgumentNullException.ThrowIfNull(prediction);
        ArgumentNullException.ThrowIfNull(predict);
        if (state.Length == 0 || state.Length % Channels != 0 || state.Length / Channels > FlowMotion.MaximumFrames
            || prediction.Length != state.Length || ReferenceEquals(state, prediction))
            throw new ArgumentException("Sampling needs separate, equally sized [frames,491] state and prediction buffers.");
        CheckFinite(state);
        const float minimumRemaining = 1f / Steps;
        for (var step = 0; step < Steps; step++)
        {
            cancellation.ThrowIfCancellationRequested();
            var time = step / (float)Steps;
            var delta = (step + 1) / (float)Steps - time;
            predict(state, time, prediction, cancellation);
            cancellation.ThrowIfCancellationRequested();
            CheckFinite(prediction);
            var remaining = Math.Max(1f - time, minimumRemaining);
            for (var i = 0; i < state.Length; i++)
                state[i] += (prediction[i] - state[i]) / remaining * delta;
            CheckFinite(state);
        }
    }

    static void CheckFinite(ReadOnlySpan<float> values)
    {
        foreach (var value in values)
            if (!float.IsFinite(value)) throw new ArithmeticException("FlowHMR sampling produced or received a non-finite latent.");
    }
}
notpointless.chomnr_humanoid_mocap_x / HostedCaptureOptions.cs
Game library
using System;

namespace HumanoidMocapX;

/// <summary>Video-range and model settings sent to a processing host. Times are source seconds.</summary>
public sealed record HostedCaptureOptions(FlowModel Model, int CameraInterval, double Start, double? End)
{
    /// <summary>Rejects unsupported models, sampling intervals and invalid time ranges.</summary>
    public void Validate()
    {
        new CaptureOptions { Model = Model, CameraInterval = CameraInterval }.Validate();
        if (!double.IsFinite(Start) || Start < 0 || End is double end && (!double.IsFinite(end) || end <= Start))
            throw new ArgumentException("The video range needs a finite, nonnegative start and a later end.");
    }
}

/// <summary>Protocol version, processor readiness, the upload limit in bytes, how many unfinished
/// jobs one account may have, how many jobs wait and run across all accounts, how many process at
/// once, and the longest video range in seconds. A provider's site reports the signed-in account's
/// own limits and whether its jobs wait in the priority queue.</summary>
public sealed record HostedCapabilities(int Protocol, bool ProcessingAvailable, long MaximumUploadBytes,
    int MaximumActiveJobs = 1, int QueueLength = 0, int Processing = 0, int ConcurrentJobs = 1,
    double? MaximumClipSeconds = null, bool Priority = false);

/// <summary>Job state returned by the host. QueuePosition is one-based while queued, out of
/// QueueLength waiting jobs; Progress (0 to 1) is set while processing. SecondsUntilStart and
/// SecondsRemaining are the host's estimates. ExpiresAt is when a finished job and its result
/// are deleted. Priority jobs wait ahead of the others. IDs are opaque; result URLs are derived locally.</summary>
#nullable enable annotations
public sealed record HostedJob(Guid Id, string State, string Message, int? QueuePosition = null, string? Name = null,
    DateTimeOffset CreatedAt = default, int QueueLength = 0, double? Progress = null, int? SecondsUntilStart = null,
    int? SecondsRemaining = null, DateTimeOffset? ExpiresAt = null, bool Priority = false);
#nullable restore
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Formats/Fbx/FbxImportOptions.cs
Game library
#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Threading;
using HumanoidMocapX.Core.Maths;
using HumanoidMocapX.Core.Skeleton;

namespace HumanoidMocapX.Core.Formats.Fbx;

using Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)

/// <summary>Options for <see cref="FbxImporter.Import"/>.</summary>
public sealed class FbxImportOptions
{
    /// <summary>Fixed resampling rate for all clips, frames per second.</summary>
    public float SampleFps { get; init; } = 30f;
    public long MaximumTransformSamples { get; init; } = long.MaxValue;
    public CancellationToken CancellationToken { get; init; }

    /// <summary>
    /// When the static rest pose is degenerate (Mixamo-style zeroed bind translations) and no
    /// usable BindPose node exists, sample frame 0 of the first clip as the rest pose.
    /// </summary>
    public bool RestFromFrame0WhenBindDegenerate { get; init; } = true;
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Formats/Fbx/FbxTransform.cs
Game library
#nullable enable annotations

using System;
using System.Numerics;
using HumanoidMocapX.Core.Maths;

namespace HumanoidMocapX.Core.Formats.Fbx;

using Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)

/// <summary>
/// Per-node FBX local-transform evaluation: the static pivot/pre-rotation data of one Model
/// plus the full FBX transform formula.
/// </summary>
/// <remarks>
/// The FBX SDK formula (column-vector convention, right-multiply children):
/// <code>
/// World = ParentWorld · T · Roff · Rp · Rpre · R · Rpost⁻¹ · Rp⁻¹ · Soff · Sp · S · Sp⁻¹
/// </code>
/// System.Numerics matrices are row-vector (<c>p' = p·M</c>), so the local matrix is composed
/// in reverse order with row-form factors:
/// <code>
/// Local = T(-Sp)·S·T(Sp)·T(Soff)·T(-Rp)·R(Rpre·R·Rpost⁻¹)·T(Rp)·T(Roff)·T(t)
/// World = Local · ParentWorld
/// </code>
/// <para><b>RotationOrder</b> (0=XYZ, 1=XZY, 2=YZX, 3=YXZ, 4=ZXY, 5=ZYX): the letters give the
/// application order, first letter applied first — eEulerXYZ composes <c>R = Rz·Ry·Rx</c> in
/// column convention (verified against Blender-imported ground truth of Mixamo and citizen
/// rigs). Pre/Post rotations always use XYZ order and are only applied when
/// <c>RotationActive</c> is set (matching Blender's importer; defaults to active when the
/// property is absent everywhere).</para>
/// <para><b>InheritType</b> (0=RrSs, 1=RSrs, 2=Rrs): scale is dropped to rigid transforms by
/// this importer — world matrices are evaluated with full scale, then decomposed to pos+rot
/// with scale folded into child translations — so types 0 and 1 are handled identically.
/// Files that use non-uniform scale meaningfully with InheritType 2 (no parent scale
/// propagation) are evaluated as type 0; this is a documented limitation.</para>
/// </remarks>
public sealed class FbxTransform
{
    /// <summary>Static "Lcl Translation" default (native units).</summary>
    public Vector3 LclTranslation { get; init; }

    /// <summary>Static "Lcl Rotation" default, euler degrees in <see cref="RotationOrder"/>.</summary>
    public Vector3 LclRotationDeg { get; init; }

    /// <summary>Static "Lcl Scaling" default.</summary>
    public Vector3 LclScaling { get; init; } = Vector3.One;

    /// <summary>PreRotation as a quaternion (identity when inactive or absent).</summary>
    public Quaternion PreRotation { get; init; } = Quaternion.Identity;

    /// <summary>PostRotation as a quaternion (identity when inactive or absent).</summary>
    public Quaternion PostRotation { get; init; } = Quaternion.Identity;

    /// <summary>RotationOffset (Roff).</summary>
    public Vector3 RotationOffset { get; init; }

    /// <summary>RotationPivot (Rp).</summary>
    public Vector3 RotationPivot { get; init; }

    /// <summary>ScalingOffset (Soff).</summary>
    public Vector3 ScalingOffset { get; init; }

    /// <summary>ScalingPivot (Sp).</summary>
    public Vector3 ScalingPivot { get; init; }

    /// <summary>Euler application order code, 0=XYZ … 5=ZYX (see class remarks).</summary>
    public int RotationOrder { get; init; }

    /// <summary>InheritType 0=RrSs, 1=RSrs, 2=Rrs (see class remarks for handling).</summary>
    public int InheritType { get; init; }

    /// <summary>Reads the static transform data of a Model from its (template-backed) properties.</summary>
    public static FbxTransform FromModel(FbxScene scene, FbxObject model)
    {
        ArgumentNullException.ThrowIfNull(scene);
        ArgumentNullException.ThrowIfNull(model);

        // Pre/Post rotation participate only when RotationActive is set (Blender-compatible).
        // When the property is absent on both the object and its template, default to active —
        // exporters that strip RotationActive but keep PreRotation expect it applied.
        bool rotationActive = scene.FindProperty(model, "RotationActive") is { } ra
            ? ra.GetInt() != 0
            : true;

        var pre = scene.GetVector3(model, "PreRotation", Vector3.Zero);
        var post = scene.GetVector3(model, "PostRotation", Vector3.Zero);

        return new FbxTransform
        {
            LclTranslation = scene.GetVector3(model, "Lcl Translation", Vector3.Zero),
            LclRotationDeg = scene.GetVector3(model, "Lcl Rotation", Vector3.Zero),
            LclScaling = scene.GetVector3(model, "Lcl Scaling", Vector3.One),
            PreRotation = rotationActive ? EulerDegreesToQuaternion(pre, 0) : Quaternion.Identity,
            PostRotation = rotationActive ? EulerDegreesToQuaternion(post, 0) : Quaternion.Identity,
            RotationOffset = scene.GetVector3(model, "RotationOffset", Vector3.Zero),
            RotationPivot = scene.GetVector3(model, "RotationPivot", Vector3.Zero),
            ScalingOffset = scene.GetVector3(model, "ScalingOffset", Vector3.Zero),
            ScalingPivot = scene.GetVector3(model, "ScalingPivot", Vector3.Zero),
            RotationOrder = scene.GetInt(model, "RotationOrder", 0),
            InheritType = scene.GetInt(model, "InheritType", 0),
        };
    }

    /// <summary>
    /// Local matrix (row-vector layout) for given TRS values; pass the Lcl defaults for the
    /// rest pose or per-frame sampled values for animation.
    /// </summary>
    public Matrix4x4 LocalMatrix(Vector3 translation, Vector3 rotationDeg, Vector3 scaling)
    {
        // Column chain R-part: Rpre · R · Rpost⁻¹  →  our quaternion convention (a*b applies
        // b first) composes the same way.
        var rotation = MathQ.Normalize(
            PreRotation *
            EulerDegreesToQuaternion(rotationDeg, RotationOrder) *
            Quaternion.Conjugate(PostRotation));

        // Row-vector composition, first-applied factor leftmost (see class remarks).
        var m = Matrix4x4.CreateTranslation(-ScalingPivot);
        m *= Matrix4x4.CreateScale(scaling);
        m *= Matrix4x4.CreateTranslation(ScalingPivot + ScalingOffset - RotationPivot);
        m *= Matrix4x4.CreateFromQuaternion(rotation);
        m *= Matrix4x4.CreateTranslation(RotationPivot + RotationOffset + translation);
        return m;
    }

    /// <summary>Local matrix from the static Lcl defaults (rest evaluation, no animation).</summary>
    public Matrix4x4 LocalMatrixDefault() => LocalMatrix(LclTranslation, LclRotationDeg, LclScaling);

    /// <summary>
    /// Converts FBX euler angles (degrees) to a quaternion for the given RotationOrder code.
    /// The order letters list the application sequence (XYZ = X first, then Y, then Z).
    /// </summary>
    public static Quaternion EulerDegreesToQuaternion(Vector3 degrees, int order)
    {
        const float degToRad = MathF.PI / 180f;
        var qx = Quaternion.CreateFromAxisAngle(Vector3.UnitX, degrees.X * degToRad);
        var qy = Quaternion.CreateFromAxisAngle(Vector3.UnitY, degrees.Y * degToRad);
        var qz = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, degrees.Z * degToRad);

        // q = third * second * first (our convention applies the right factor first).
        return order switch
        {
            0 => qz * qy * qx, // XYZ
            1 => qy * qz * qx, // XZY
            2 => qx * qz * qy, // YZX
            3 => qz * qx * qy, // YXZ
            4 => qy * qx * qz, // ZXY
            5 => qx * qy * qz, // ZYX
            6 => qz * qy * qx, // eSphericXYZ — treated as XYZ
            _ => throw new FormatException($"Unsupported FBX RotationOrder {order}."),
        };
    }

    /// <summary>
    /// Extracts the rigid part of a (possibly scaled) world matrix: translation taken directly,
    /// rotation from the orthonormalized basis. Scale is thereby folded into child translations
    /// when parent-relative transforms are derived from rigid worlds. Mirrored (negative
    /// determinant) bases fall back to the dominant proper rotation (best effort — mirrored
    /// skeletons are not meaningfully supported).
    /// </summary>
    public static XForm ToRigid(in Matrix4x4 world)
    {
        var pos = world.Translation;

        var x = new Vector3(world.M11, world.M12, world.M13);
        var y = new Vector3(world.M21, world.M22, world.M23);
        var z = new Vector3(world.M31, world.M32, world.M33);

        x = SafeNormalize(x, Vector3.UnitX);
        y = SafeNormalize(y, Vector3.UnitY);
        z = SafeNormalize(z, Vector3.UnitZ);

        // Mirrored basis: flip the third axis to restore a proper rotation.
        if (Vector3.Dot(Vector3.Cross(x, y), z) < 0f)
            z = -z;

        var m = new Matrix4x4(
            x.X, x.Y, x.Z, 0f,
            y.X, y.Y, y.Z, 0f,
            z.X, z.Y, z.Z, 0f,
            0f, 0f, 0f, 1f);

        return new XForm(pos, MathQ.Normalize(Quaternion.CreateFromRotationMatrix(m)));
    }

    private static Vector3 SafeNormalize(Vector3 v, Vector3 fallback)
    {
        float lsq = v.LengthSquared();
        if (!float.IsFinite(lsq) || lsq < 1e-20f)
            return fallback;
        return v / MathF.Sqrt(lsq);
    }
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Formats/Fbx/ModelDocFbxExport.cs
Game library
using System;
using System.Collections.Generic;
using System.Linq;
using HumanoidMocapX.Core.Maths;
using HumanoidMocapX.Core.Skeleton;

namespace HumanoidMocapX.Core.Formats.Fbx;
using SkeletonModel = HumanoidMocapX.Core.Skeleton.Skeleton;

/// <summary>FBX with the source-to-engine scale baked into every translation for direct ModelDoc import.</summary>
public static class ModelDocFbxExport
{
	/// <summary>Uses Humanoid Retargeter's source scale for centimetre rigs; compiled engine rigs already use inches.</summary>
	public static byte[] Write( SkeletonModel skeleton, string name, IReadOnlyList<XForm[]> frames,
		IReadOnlyList<double> times, double fps, TargetUpAxis axis, string motionSpace )
	{
		ArgumentNullException.ThrowIfNull( skeleton );
		ArgumentNullException.ThrowIfNull( frames );
		if ( frames.Count is < 1 or > 108000 || skeleton.Count is < 1 or > 1024
			|| (long)frames.Count * skeleton.Count > FbxAnimationWriter.MaximumTransformSamples )
			throw new ArgumentException( "Animation exceeds the export budget. Select a shorter range." );
		if ( axis is not (TargetUpAxis.YUpCm or TargetUpAxis.ZUpEngine) )
			throw new ArgumentOutOfRangeException( nameof( axis ) );

		// Like Retargeter's ModelModifier_ScaleAndMirror, this converts raw source values.
		// UnitScaleFactor alone is insufficient for ModelDoc's raw-unit import. Bake the
		// factor into bind positions, all local translations, root motion and appended props.
		if ( axis == TargetUpAxis.YUpCm )
		{
			XForm Scale( XForm pose ) => new( pose.Pos * RetargetTargetSpec.SboxSourceScale, pose.Rot );
			skeleton = SkeletonModel.Create( skeleton.Bones.Select( bone => new BoneDefinition(
				bone.Name, bone.ParentIndex < 0 ? null : skeleton[ bone.ParentIndex ].Name,
				Scale( bone.RestLocal ) ) ).ToArray() );
			frames = frames.Select( frame => frame.Select( Scale ).ToArray() ).ToArray();
		}

		return FbxAnimationWriter.Write( skeleton, name, frames, times, fps,
			axis == TargetUpAxis.YUpCm ? 1 : 2, 2.54, motionSpace );
	}
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/InspectResult.cs
Game library
#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Linq;
using HumanoidMocapX.Core.Mapping;
using HumanoidMocapX.Core.Maths;
using HumanoidMocapX.Core.Target;
using HumanoidMocapX.Core.Skeleton;

namespace HumanoidMocapX.Core;

/// <summary>
/// Result of <see cref="Retargeter.Inspect"/>: the mapping report plus the file's take
/// metadata, so UI listings can expand a multi-take file into one entry per take (each
/// convertible independently via <see cref="RetargetRequest.TakeIndex"/>).
/// </summary>
public sealed class InspectResult
{
    /// <summary>Mapping report from the same preset-then-auto cascade conversion uses.</summary>
    public required MappingReportInfo Mapping { get; init; }

    /// <summary>Names of the file's animation takes, in take-index order (the index is what
    /// <see cref="RetargetRequest.TakeIndex"/> accepts). Empty when the file has no animation.</summary>
    public required IReadOnlyList<string> TakeNames { get; init; }

    /// <summary>Number of animation takes in the file.</summary>
    public int TakeCount => TakeNames.Count;
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Motion/ArmSettings.cs
Game library
using System;
using System.Numerics;
using HumanoidMocapX.Core.Maths;

namespace HumanoidMocapX.Core.Motion;
using Vector3 = System.Numerics.Vector3;

public sealed class ArmSettings
{
    public Vector3 Shoulder { get; set; } = new(.18f,-.15f,0);
    public Vector3 ElbowTarget { get; set; } = new(.4f,-.4f,.2f);
    public float UpperLength { get; set; } = .28f;
    public float ForearmLength { get; set; } = .25f;
    public float MaximumReach { get; set; } = .995f;
    public float MinimumElbowDegrees { get; set; } = 5;
    public float MaximumElbowDegrees { get; set; } = 155;
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Motion/CaptureLegReach.cs
Game library
using System;

namespace HumanoidMocapX.Core.Motion;

using Vector3 = System.Numerics.Vector3;

/// <summary>Leaves a small knee bend when moving the pelvis to reach captured foot targets.</summary>
internal static class CaptureLegReach
{
	// Exact full extension is singular: a millimetre of ankle travel can unfold the knee
	// by centimetres. Reserve half a percent of reach and enter the correction smoothly.
	internal const float ReachFraction = .995f;

	internal static float Lowering( Vector3 hipToFoot, Vector3 up, float length )
	{
		var vertical = Vector3.Dot( hipToFoot, up );
		var horizontal = hipToFoot - up * vertical;
		var reach = length * ReachFraction;
		if ( length <= 0 || vertical <= 0 || horizontal.LengthSquared() >= reach * reach ) return 0;

		var deficit = vertical - MathF.Sqrt( reach * reach - horizontal.LengthSquared() );
		var ease = length * .01f;
		// Smooth positive part, evaluated without subtracting two nearly equal numbers.
		var diagonal = MathF.Sqrt( deficit * deficit + ease * ease );
		return deficit >= 0 ? (deficit + diagonal) * .5f : ease * ease / (2 * (diagonal - deficit));
	}
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Preview/PreviewFrameBuffer.cs
Game library
using System;

namespace HumanoidMocapX.Core.Preview;

/// <summary>Owns a bounded RGBA preview frame. Reuses storage until the preview size
/// changes; callers must synchronize concurrent readers and writers.</summary>
public sealed class PreviewFrameBuffer
{
    const int MaximumWidth = 960, MaximumHeight = 540, PixelBytes = 4;
    byte[] pixels = Array.Empty<byte>();
    /// <summary>Width of the owned preview in pixels; zero before the first frame.</summary>
    public int Width { get; private set; }
    /// <summary>Height of the owned preview in pixels; zero before the first frame.</summary>
    public int Height { get; private set; }
    /// <summary>Increases after each successful copy so consumers can skip unchanged frames.</summary>
    public long Version { get; private set; }
    /// <summary>Borrowed pixels, valid until the next Copy call.</summary>
    public ReadOnlySpan<byte> Pixels => pixels;

    /// <summary>Copies a packed RGBA frame, reducing it to fit 960×540 without changing
    /// aspect ratio. Rejects nonpositive dimensions and an incorrect byte count.</summary>
    public void Copy(ReadOnlySpan<byte> source, int width, int height)
    {
        if (width < 1 || height < 1 || (long)width * height * PixelBytes != source.Length)
            throw new ArgumentException("Video preview requires a complete packed RGBA frame.");
        var scale = Math.Min(1, Math.Min((double)MaximumWidth / width, (double)MaximumHeight / height));
        var targetWidth = Math.Max(1, (int)(width * scale));
        var targetHeight = Math.Max(1, (int)(height * scale));
        var length = targetWidth * targetHeight * PixelBytes;
        if (pixels.Length != length) pixels = new byte[length];
        if (targetWidth == width && targetHeight == height) source.CopyTo(pixels);
        else
            for (var y = 0; y < targetHeight; y++)
                for (var x = 0; x < targetWidth; x++)
                {
                    var from = ((long)y * height / targetHeight * width + (long)x * width / targetWidth) * PixelBytes;
                    var to = (y * targetWidth + x) * PixelBytes;
                    source.Slice((int)from, PixelBytes).CopyTo(pixels.AsSpan(to, PixelBytes));
                }
        Width = targetWidth; Height = targetHeight; Version++;
    }
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Retargeter.cs
Game library
#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;
using HumanoidMocapX.Core.Cleanup;
using HumanoidMocapX.Core.Formats;
using HumanoidMocapX.Core.Formats.Dmx;
using HumanoidMocapX.Core.Formats.Fbx;
using HumanoidMocapX.Core.Formats.Gltf;
using HumanoidMocapX.Core.Mapping;
using HumanoidMocapX.Core.Maths;
using HumanoidMocapX.Core.Skeleton;
using HumanoidMocapX.Core.Solve;
using HumanoidMocapX.Core.Target;
using SkeletonModel = HumanoidMocapX.Core.Skeleton.Skeleton;

namespace HumanoidMocapX.Core;

using Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)

/// <summary>
/// Engine-agnostic pipeline facade (design §5): bytes in → DMX + vmdl text out. Composes
/// import → mapping → solve → cleanup → IK baking → DMX → vmdl assembly. Batch is
/// first-class: N files × all takes per file → ONE combined vmdl, with per-request profile
/// detection (a batch may mix Mixamo + ActorCore + BVH sources) and per-clip failure
/// isolation. No file IO anywhere in this type — callers pass bytes/strings and write the
/// returned strings.
/// </summary>
/// <remarks>
/// Pipeline per clip:
/// <list type="number">
/// <item><b>Import</b> — format by file extension (<c>.hmotion</c>/<c>.fbx</c>/<c>.glb</c>/
/// <c>.gltf</c>/<c>.vrm</c>), content sniff as fallback → <see cref="SourceScene"/> (cm,
/// native axes).</item>
/// <item><b>Mapping</b> — per request: <see cref="RetargetRequest.MappingOverride"/> wins;
/// else <see cref="ProfileDetector.Detect"/> over the preset library (user presets are
/// loaded Editor-side and arrive as overrides); else <see cref="AutoMapper.Map"/> as best
/// effort with <see cref="MappingReportInfo.NeedsUserDecision"/> set when its confidence is
/// below <see cref="ProfileDetector.DetectionThreshold"/>.</item>
/// <item><b>Solve</b> — <see cref="GeometricSolver"/> per take (clip name = take name, or
/// <see cref="RetargetRequest.ClipNameOverride"/> + index).</item>
/// <item><b>Cleanup</b> (target space) — <see cref="FootPlant"/> when enabled (chains from
/// the target rig's UpperLeg/LowerLeg/Foot/Toe roles, up axis from the TARGET character
/// frame, fps from the clip); optional arm <see cref="EffectorIk"/> (off by default — the
/// solver already matches anatomical directions); <see cref="RootMotion"/> per mode (see
/// below).</item>
/// <item><b>IK baking</b> — <see cref="IkBoneBaker.Bake"/> when the rig has
/// <see cref="BoneClass.IkBaked"/> bones.</item>
/// <item><b>DMX</b> — <see cref="DmxWriter"/> over the target skeleton.</item>
/// <item><b>Assembly</b> — <see cref="VmdlWriter.GenerateStandalone"/> over all successful
/// clips, plus <see cref="VmdlAugmenter.Augment"/> when
/// <see cref="BatchOptions.AugmentVmdlText"/> is provided; clip-name collisions are
/// auto-suffixed (<c>_2</c>, <c>_3</c>, …) across the batch.</item>
/// </list>
/// <para><b>Root-motion ↔ target mapping.</b> <see cref="RootMotionMode.Extract"/> bakes the
/// ground-projected hips path onto the target's dedicated root bone — defined as a parentless
/// <see cref="BoneClass.Animated"/> bone that is an ancestor of (and distinct from) the Hips
/// bone. The s&amp;box rig has NO such bone (pelvis is itself parentless; root_IK is IkBaked),
/// so there Extract leaves the frames untouched, adds a report note, and instead sets
/// <see cref="AnimEntry.ExtractMotion"/> on the clip's vmdl entry: Source 2 extracts the
/// ground-plane translation from <see cref="RetargetTargetSpec.DefaultRootBone"/> at compile
/// time, which is the engine-native equivalent. The ExtractMotion flag is set for every
/// Extract request either way. <see cref="RootMotionMode.InPlace"/> always operates on the
/// hips channels directly and needs no dedicated root.</para>
/// </remarks>
public static class Retargeter
{
	/// <summary>
	/// Applies the same mapping, diagnostics, and mid-pose bind-rest selection used by
	/// <see cref="ConvertBatch"/>, while leaving the sampled clips available to an editor
	/// integration that needs an in-memory target rather than DMX output.
	/// </summary>
	public static ResolvedSource ResolveSource( SourceScene scene, MappingResult? mappingOverride = null,
		Func<string, MappingResult?>? userPresetLookup = null )
	{
		ArgumentNullException.ThrowIfNull( scene );
		var (map, report) = ResolveMapping( scene.Skeleton, mappingOverride, userPresetLookup, scene.AuthoredMapping );
		foreach ( var note in scene.Notes ) AddNote( report, note );
		scene = MaybeAdoptBindRest( scene, map, report );
		return new( scene, map, report );
	}

    /// <summary>Converts one source file — all takes, or only
    /// <see cref="RetargetRequest.TakeIndex"/> when set. Equivalent to a one-request batch.</summary>
    public static RetargetResult Convert(RetargetRequest request, RetargetTargetSpec target)
    {
        ArgumentNullException.ThrowIfNull(request);
        var batch = ConvertBatch(new[] { request }, target);
        return new RetargetResult
        {
            Clips = batch.Clips,
            StandaloneVmdl = batch.StandaloneVmdl,
            Errors = batch.Errors,
        };
    }

    /// <summary>
    /// Converts a batch of source files against one target. Per-request profile detection,
    /// per-clip failure isolation (a bad file yields a failed <see cref="ClipResult"/> and
    /// the batch continues), one standalone vmdl with every successful clip, optional
    /// augmentation of an existing vmdl.
    /// </summary>
    public static RetargetBatchResult ConvertBatch(
        IReadOnlyList<RetargetRequest> requests, RetargetTargetSpec target, BatchOptions? options = null)
    {
        ArgumentNullException.ThrowIfNull(requests);
        ArgumentNullException.ThrowIfNull(target);
        options ??= new BatchOptions();

        var context = new TargetContext(target.Rig);
        var result = new RetargetBatchResult();
        var usedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        var entries = new List<AnimEntry>();

        // Augment mode: names already taken in the existing vmdl's AnimationList must not be
        // silently repointed — seed the collision set with every existing node name EXCEPT
        // our own AnimFiles (source_filename under DmxFolderRelative), which are replaceable
        // so re-running the same batch stays idempotent.
        if (options.AugmentVmdlText is not null)
            SeedUsedNamesFromExistingVmdl(options.AugmentVmdlText, options.DmxFolderRelative, usedNames);

        var mappedPinky = false;
        foreach (var request in requests)
        {
            if (request is null)
                continue;
            mappedPinky |= ProcessRequest(
                request, target, context, options, usedNames, result.Clips, entries);
        }

        foreach (var clip in result.Clips)
        {
            if (!clip.Success)
                result.Errors.Add($"{clip.SourceFileName}: {clip.Error}");
        }

        // Locomotion families are detected on the FINAL (collision-suffixed) clip names so
        // the blend grids reference exactly what the vmdl registers; folder/blend names are
        // made unique against the same name set the clips used.
        IReadOnlyList<LocomotionSetSpec>? locomotionSets = null;
        if (options.DetectLocomotionSets)
        {
            var (sets, reports) = LocomotionSetDetector.Detect(
                entries, usedNames, options.AutoSuffixCollisions);
            result.LocomotionSets.AddRange(reports);
            if (sets.Count > 0)
                locomotionSets = sets;
        }

        // The target's OWN embedded animations ride along every generated vmdl (an FBX
        // picked as target keeps its animation next to the retargeted ones). Skipped when
        // a same-named entry is already registered (idempotent re-runs / augment targets
        // that carry them from an earlier conversion); the retargeted clips claimed their
        // names first, so an embedded take never displaces a converted clip.
        if (target.ExtraAnimFiles is { Count: > 0 })
        {
            foreach (var extra in target.ExtraAnimFiles)
            {
                if (usedNames.Add(extra.Name))
                    entries.Add(extra);
            }
        }

        result.StandaloneVmdl = VmdlWriter.GenerateStandalone(
            target.BaseModelPath, entries, target.VmdlScale, target.DefaultRootBone,
            locomotionSets, target.MeshFilePath, target.MeshImportScale, target.MaterialRemaps,
            target.MeshImportNames);

        if (options.AugmentVmdlText is not null)
        {
            try
            {
                var removedSequences = new List<string>();
                result.AugmentedVmdl = VmdlAugmenter.Augment(
                    options.AugmentVmdlText, entries, out _,
                    new AugmentOptions
                    {
                        DefaultRootBone = target.DefaultRootBone,
                        // The citizen base model copies ring→pinky via its CopyPinky
                        // constraints; when this batch actually drives the pinky, the
                        // augmented vmdl must neutralize them or the exported pinky
                        // channels get overridden at runtime.
                        NeutralizePinkyConstraints = mappedPinky,
                        LocomotionSets = locomotionSets,
                        // Same ownership rule the name seeding above used: pipeline-owned
                        // locomotion folders (every AnimFile sourced under our DMX folder)
                        // are replaceable wholesale on re-runs.
                        DmxFolderRelative = options.DmxFolderRelative,
                        // Stale entries whose DMX the caller found missing on disk: keep
                        // them and the WHOLE vmdl stops compiling ("Node 'X' resolve
                        // failure"), new sequences included.
                        MissingSourceFiles = options.MissingAnimSources,
                    },
                    removedSequences);
                foreach (var name in removedSequences)
                {
                    result.Warnings.Add(
                        $"removed stale sequence '{name}' from the augmented vmdl: its "
                        + "animation source file no longer exists on disk (a missing source "
                        + "fails the whole model recompile)");
                }
            }
            catch (Exception e)
            {
                result.Errors.Add($"vmdl augmentation failed: {e.Message}");
            }
        }

        return result;
    }

    /// <summary>Collects names already present in the existing vmdl's AnimationList that the
    /// batch must not reuse (everything except our own replaceable AnimFiles).</summary>
    private static void SeedUsedNamesFromExistingVmdl(
        string vmdlText, string dmxFolderRelative, HashSet<string> usedNames)
    {
        Kv3Document doc;
        try
        {
            doc = Kv3.Parse(vmdlText);
        }
        catch (FormatException)
        {
            return; // the augmentation step itself surfaces the parse error
        }

        if (doc.Root is not KvObject root || root.GetOrNull("rootNode") is not KvObject rootNode
            || rootNode.GetOrNull("children") is not KvArray children)
            return;
        var animList = children.Items.OfType<KvObject>()
            .FirstOrDefault(o => o.GetString("_class") == "AnimationList");
        if (animList?.GetOrNull("children") is not KvArray items)
            return;

        var folder = dmxFolderRelative.Replace('\\', '/').TrimEnd('/');
        SeedNames(items, folder, usedNames);
    }

    /// <summary>
    /// Recursive seeding step: every named AnimationList node reserves its name EXCEPT our
    /// own replaceable output — AnimFiles whose source lives in the batch's DMX folder, and
    /// locomotion Folders consisting entirely of such AnimFiles (a re-run replaces the whole
    /// folder, so neither its name nor its content may block the new batch's names). Foreign
    /// folders are seeded by name and their content seeded recursively.
    /// </summary>
    private static void SeedNames(KvArray items, string dmxFolder, HashSet<string> usedNames)
    {
        foreach (var node in items.Items.OfType<KvObject>())
        {
            var name = node.GetString("name");
            var cls = node.GetString("_class");

            if (cls == "AnimFile")
            {
                if (!string.IsNullOrEmpty(name) && !IsOurAnimFile(node, dmxFolder))
                    usedNames.Add(name);
                continue;
            }

            if (cls == "Folder")
            {
                if (IsOurLocomotionFolder(node, dmxFolder))
                    continue; // replaceable wholesale — nothing inside reserves a name
                if (!string.IsNullOrEmpty(name))
                    usedNames.Add(name);
                if (node.GetOrNull("children") is KvArray nested)
                    SeedNames(nested, dmxFolder, usedNames);
                continue;
            }

            if (!string.IsNullOrEmpty(name))
                usedNames.Add(name);
        }
    }

    /// <summary>Whether an AnimFile was written by this pipeline: its source_filename sits
    /// inside the batch's DMX folder.</summary>
    private static bool IsOurAnimFile(KvObject node, string dmxFolder)
    {
        var source = (node.GetString("source_filename") ?? "").Replace('\\', '/');
        return dmxFolder.Length == 0
            ? !source.Contains('/')
            : source.StartsWith(dmxFolder + "/", StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>Whether a Folder is a locomotion group this pipeline spliced: it contains at
    /// least one AnimFile and every AnimFile inside it (recursively) is ours.</summary>
    private static bool IsOurLocomotionFolder(KvObject folderNode, string dmxFolder)
    {
        var sawAnimFile = false;
        return Walk(folderNode) && sawAnimFile;

        bool Walk(KvObject node)
        {
            if (node.GetString("_class") == "AnimFile")
            {
                sawAnimFile = true;
                return IsOurAnimFile(node, dmxFolder);
            }
            if (node.GetOrNull("children") is KvArray children)
            {
                foreach (var child in children.Items.OfType<KvObject>())
                {
                    if (!Walk(child))
                        return false;
                }
            }
            return true;
        }
    }

    /// <summary>
    /// Detection-only entry point for UI listings: imports the file and runs the same
    /// preset-then-auto mapping as conversion, without solving anything. Also reports the
    /// file's take metadata (clip names, in take-index order) so listings can expand a
    /// multi-take file into one entry per take. Throws <see cref="FormatException"/> when
    /// the file is unreadable.
    /// </summary>
    public static InspectResult Inspect(byte[] sourceData, string fileName)
    {
        ArgumentNullException.ThrowIfNull(sourceData);
        ArgumentNullException.ThrowIfNull(fileName);
        var scene = ImportSource(sourceData, fileName);
        var takeNames = new List<string>(scene.Clips.Count);
        foreach (var clip in scene.Clips)
            takeNames.Add(clip.Name);
        return new InspectResult
        {
            Mapping = ResolveMapping(scene.Skeleton, authoredMapping: scene.AuthoredMapping).Report,
            TakeNames = takeNames,
        };
    }

    // ================================================================ per-request pipeline

    /// <summary>Runs one request end to end. Returns true when at least one clip converted
    /// successfully with a mapping that drives a pinky role (CopyPinky handling).</summary>
    private static bool ProcessRequest(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        BatchOptions options, HashSet<string> usedNames,
        List<ClipResult> clips, List<AnimEntry> entries)
    {
        var sourceId = request.SourceId ?? request.SourceFileName;
        SourceScene scene;
        MappingReportInfo report;
        MappingResult map;
        try
        {
            scene = ImportSource(
                request.SourceData, request.SourceFileName, request.SampleFps,
                request.ExternalBufferResolver);
            (map, report) = ResolveMapping(
                scene.Skeleton, request.MappingOverride, authoredMapping: scene.AuthoredMapping);
            // Import diagnostics (mid-pose exports, cross-stack static disagreements, ...)
            // ride the mapping report so UIs can surface them next to the conversion result.
            foreach (var note in scene.Notes)
                AddNote(report, note);
            scene = MaybeAdoptBindRest(scene, map, report);
        }
        catch (Exception e)
        {
            clips.Add(new ClipResult
            {
                ClipName = FileStem(request.SourceFileName),
                SourceFileName = request.SourceFileName,
                SourceId = sourceId,
                Success = false,
                Error = e.Message,
            });
            return false;
        }

        if (scene.Clips.Count == 0)
        {
            clips.Add(new ClipResult
            {
                ClipName = FileStem(request.SourceFileName),
                SourceFileName = request.SourceFileName,
                SourceId = sourceId,
                Mapping = report,
                Success = false,
                Error = "Source file contains no animation takes.",
            });
            return false;
        }

        var mapsPinky = MapsPinkyRole(map);
        if (mapsPinky && options.AugmentVmdlText is null
            && target.BaseModelPath == RetargetTargetSpec.SboxHumanMalePath)
        {
            // A standalone child vmdl cannot override the base model's AnimConstraintList:
            // the citizen's CopyPinky (ring → pinky orient copy) keeps driving the pinky at
            // runtime even though the DMX carries real pinky channels.
            AddNote(report,
                "Pinky channels are exported, but the base model's CopyPinky constraints "
                + "(ring → pinky copy) cannot be overridden from a standalone vmdl, so the "
                + "pinky will visibly mirror the ring finger's motion in engine — use "
                + "augment mode (add to the existing vmdl) to neutralize them.");
        }
        if (target.UpAxis == TargetUpAxis.ZUpEngine)
        {
            AddNote(report,
                "Target rig is engine-space (Z-up, inches): the DMX declares a Z-up axis "
                + "system so resourcecompiler performs no Y-up conversion (best-effort — "
                + "verify the compiled sequence on engine-space targets).");
        }

        // External clip definitions (Unity .fbx.meta clipAnimations): one output clip per
        // DEFINITION, sliced out of its take; TakeIndex addresses the definitions then
        // (see RetargetRequest.ClipDefinitions).
        if (request.ClipDefinitions is { Count: > 0 } clipDefs)
        {
            return ProcessClipDefinitions(
                request, target, context, options, usedNames, clips, entries,
                scene, map, report, sourceId, mapsPinky, clipDefs);
        }

        // TakeIndex narrows the conversion to a single take (UI per-take entries submit one
        // request per selected take); null keeps the historical convert-all-takes behavior.
        var takeStart = 0;
        var takeEnd = scene.Clips.Count;
        if (request.TakeIndex is { } takeIndex)
        {
            if (takeIndex < 0 || takeIndex >= scene.Clips.Count)
            {
                clips.Add(new ClipResult
                {
                    ClipName = FileStem(request.SourceFileName),
                    SourceFileName = request.SourceFileName,
                    SourceId = sourceId,
                    Mapping = report,
                    Success = false,
                    Error = $"Take index {takeIndex} is out of range: the source file "
                        + $"contains {scene.Clips.Count} take(s).",
                });
                return false;
            }
            takeStart = takeIndex;
            takeEnd = takeIndex + 1;
        }

        var anyPinkySuccess = false;
        for (var take = takeStart; take < takeEnd; take++)
        {
            var clipName = UniqueClipName(
                SanitizeClipName(RequestedClipName(request, scene, take)),
                usedNames, options.AutoSuffixCollisions);
            anyPinkySuccess |= ConvertOne(
                request, target, context, options, usedNames, clips, entries,
                scene, map, report, sourceId, mapsPinky, take, clipName);
        }

        return anyPinkySuccess;
    }

    /// <summary>
    /// The definitions variant of the take loop: each <see cref="ExternalClipDef"/> becomes
    /// its own clip result — the definition's take is located by
    /// <see cref="ExternalClipDef.TakeName"/> (falling back to the file's first take), sliced
    /// to the definition's native-frame range via <see cref="UnityMeta.Slice"/> and solved as
    /// a single-clip scene. Returns true when at least one clip converted successfully with a
    /// pinky-driving mapping.
    /// </summary>
    private static bool ProcessClipDefinitions(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        BatchOptions options, HashSet<string> usedNames,
        List<ClipResult> clips, List<AnimEntry> entries,
        SourceScene scene, MappingResult map, MappingReportInfo report,
        string sourceId, bool mapsPinky, IReadOnlyList<ExternalClipDef> clipDefs)
    {
        var defStart = 0;
        var defEnd = clipDefs.Count;
        if (request.TakeIndex is { } defIndex)
        {
            if (defIndex < 0 || defIndex >= clipDefs.Count)
            {
                clips.Add(new ClipResult
                {
                    ClipName = FileStem(request.SourceFileName),
                    SourceFileName = request.SourceFileName,
                    SourceId = sourceId,
                    Mapping = report,
                    Success = false,
                    Error = $"Clip-definition index {defIndex} is out of range: the request "
                        + $"carries {clipDefs.Count} clip definition(s).",
                });
                return false;
            }
            defStart = defIndex;
            defEnd = defIndex + 1;
        }

        var anyPinkySuccess = false;
        for (var d = defStart; d < defEnd; d++)
        {
            var def = clipDefs[d];
            var requestedName = !string.IsNullOrWhiteSpace(def.Name)
                ? def.Name
                : clipDefs.Count > 1 ? $"{FileStem(request.SourceFileName)}_{d + 1}" : FileStem(request.SourceFileName);
            var clipName = UniqueClipName(
                SanitizeClipName(requestedName), usedNames, options.AutoSuffixCollisions);

            var take = TakeForDefinition(scene, def);
            var sliced = UnityMeta.Slice(scene.Clips[take], def, clipName);

            // Same skeleton/axes, ONE clip: the regular pipeline then solves "take 0" of it.
            var defScene = new SourceScene(
                scene.Skeleton, new[] { sliced }, scene.UnitScaleCm,
                scene.UpAxis, scene.UpAxisSign,
                scene.FrontAxis, scene.FrontAxisSign,
                scene.CoordAxis, scene.CoordAxisSign,
                scene.OriginalUpAxis, scene.Notes)
            {
                AuthoredMapping = scene.AuthoredMapping,
                RestPlacementAuthored = scene.RestPlacementAuthored,
            };

            anyPinkySuccess |= ConvertOne(
                request, target, context, options, usedNames, clips, entries,
                defScene, map, report, sourceId, mapsPinky, take: 0, clipName);
        }

        return anyPinkySuccess;
    }

    /// <summary>The take a definition's frame range refers to: matched by take name when the
    /// definition records one (Unity's <c>takeName</c>, e.g. <c>root|Animation</c>), else —
    /// and when nothing matches — the file's first take.</summary>
    private static int TakeForDefinition(SourceScene scene, ExternalClipDef def)
    {
        if (!string.IsNullOrWhiteSpace(def.TakeName))
        {
            for (var i = 0; i < scene.Clips.Count; i++)
            {
                if (string.Equals(scene.Clips[i].Name, def.TakeName, StringComparison.Ordinal))
                    return i;
            }
        }
        return 0;
    }

    /// <summary>Solves ONE clip (take <paramref name="take"/> of <paramref name="scene"/>)
    /// end to end — solve + cleanup + DMX, plus the optional mirrored twin
    /// (<see cref="RetargetRequest.CreateMirroredVariant"/>) — appending success or failure
    /// <see cref="ClipResult"/>s (failures never abort the batch). Returns true on success
    /// with a pinky-driving mapping.</summary>
    private static bool ConvertOne(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        BatchOptions options, HashSet<string> usedNames,
        List<ClipResult> clips, List<AnimEntry> entries,
        SourceScene scene, MappingResult map, MappingReportInfo report,
        string sourceId, bool mapsPinky, int take, string clipName)
    {
        Clip clip;
        try
        {
            clip = SolveAndClean(request, target, context, scene, map, report, take, clipName);
            EmitClip(request, target, context, options, usedNames, clips, entries, report,
                sourceId, clipName, clip.Frames, clip.Fps, clip.Looping, isMirrored: false);
        }
        catch (Exception e)
        {
            clips.Add(new ClipResult
            {
                ClipName = clipName,
                SourceFileName = request.SourceFileName,
                SourceId = sourceId,
                Mapping = report,
                Success = false,
                Error = e.Message,
            });
            return false;
        }

        if (request.CreateMirroredVariant)
        {
            // The twin gets its own collision-suffixed name and its own failure isolation:
            // a mirror problem (asymmetric rig) fails ONLY the twin, never the primary clip.
            var mirroredName = UniqueClipName(
                SanitizeClipName(clipName + "_M"), usedNames, options.AutoSuffixCollisions);
            try
            {
                // SOURCE-SIDE MIRROR (southpaw G8 mirror fix, gate3_review.md 3.4 and the
                // G8 bisect evidence): the SOURCE clip is mirrored across the source
                // character's sagittal plane and the twin then runs through the COMPLETE
                // unmodified primary pipeline (solver, cleanups, ground alignment, IK
                // bake, orphan re-anchor). The emitted _M clip is a first-class primary
                // clip in every representational respect, indistinguishable from a clip
                // an animator authored mirrored. Target-space channel mirroring, however
                // geometrically exact, produced data the ENGINE's render-side sequence
                // evaluation mangles (measured: a mirrored pelvis channel alone renders
                // the whole model upside down while every CPU-side bone API reports a
                // perfect upright mirror); no data conjugation convention survived that
                // stage, so the mirror moved to the source side where no alien data
                // shape can exist.
                var mirroredScene = SourceMirror.MirrorTake(scene, map, take);
                var mirroredClip = SolveAndClean(
                    request, target, context, mirroredScene, map, report, take, mirroredName);
                EmitClip(request, target, context, options, usedNames, clips, entries, report,
                    sourceId, mirroredName, mirroredClip.Frames, mirroredClip.Fps,
                    clip.Looping, isMirrored: true);
            }
            catch (Exception e)
            {
                clips.Add(new ClipResult
                {
                    ClipName = mirroredName,
                    SourceFileName = request.SourceFileName,
                    SourceId = sourceId,
                    Mapping = report,
                    Success = false,
                    Error = $"mirrored variant: {e.Message}",
                });
            }
        }

        return mapsPinky;
    }

    /// <summary>Shared tail of clip production (primary and mirrored twin): optional footstep
    /// events, DMX serialization, the <see cref="ClipResult"/> and the vmdl
    /// <see cref="AnimEntry"/> — plus the additive (<c>_delta</c>) companion entry when
    /// <see cref="RetargetRequest.CreateAdditiveVariant"/> is on (a second AnimFile REUSING
    /// the clip's DMX with an AnimSubtract child, shipped-citizen shape; no separate
    /// <see cref="ClipResult"/> since no separate DMX exists).</summary>
    private static void EmitClip(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        BatchOptions options, HashSet<string> usedNames,
        List<ClipResult> clips, List<AnimEntry> entries,
        MappingReportInfo report, string sourceId,
        string clipName, List<XForm[]> frames, float fps, bool looping, bool isMirrored)
    {
        var events = GenerateFootsteps(request, target, context, report, frames, fps);
        var dmxFileName = SanitizeFileName(clipName) + ".dmx";
        // Embedded-mesh vmdls and compiled Z-up targets compile root channels 90° about the declared
        // up axis away from the mesh bind; child channels are unaffected. Compensate the
        // serialized copy only so compiled playback matches the solved preview.
        var dmxFrames = !string.IsNullOrEmpty(target.MeshFilePath) || target.UpAxis == TargetUpAxis.ZUpEngine
            ? CompensateEmbeddedMeshRootYaw(frames, target.Rig, target.UpAxis)
            : frames;
        var dmx = DmxWriter.Write(
            target.Rig.Skeleton, new Clip(clipName, fps, looping, dmxFrames), new DmxWriteOptions
            {
                Name = clipName,
                SourceNote = isMirrored ? request.SourceFileName + " (mirrored)" : request.SourceFileName,
                // Design §3: ConstraintDriven (twist/helper) bones keep their joints +
                // bind in the DMX but get NO channels — the model's AnimConstraintList
                // drives them. Face bones are exempt from the exclusion (rest-local
                // channels): nothing drives them in a compiled sequence, and channel-less
                // face joints bake statically (eyes out of sockets in ModelDoc). Custom
                // rigs (FromSkeleton) have NO constraint list — their helpers keep baked
                // channels or twist bones freeze (candy-wrapped wrists).
                // MIRRORED clips use the IDENTICAL exclusion set (data-shape parity with
                // primary clips, southpaw G8 mirror fix): a channel-less constraint-driven
                // bone on a mirrored-body clip is no different from one on any leftward
                // primary pose; the model's AnimConstraintList drives it at runtime either
                // way. (ClipMirror.MirrorSafeExclusions remains available for consumers
                // that need reflection-exact data for excluded bones.)
                ChannelExcludedBones = target.Rig.HelpersAreConstraintDriven
                    ? context.ConstraintDrivenBones
                    : null,
                UpAxisY = target.UpAxis == TargetUpAxis.YUpCm,
            });

        var extractMotion = request.RootMotion == RootMotionMode.Extract;

        // Additive variant: '<clip>_delta' (shipped naming), collision-suffixed like every
        // other batch name. Only the NAME is produced here — the vmdl entry below reuses
        // the base clip's DMX (resourcecompiler does the reference-frame subtraction).
        var deltaName = request.CreateAdditiveVariant
            ? UniqueClipName(
                SanitizeClipName(clipName + "_delta"), usedNames, options.AutoSuffixCollisions)
            : null;

        clips.Add(new ClipResult
        {
            ClipName = clipName,
            SourceFileName = request.SourceFileName,
            SourceId = sourceId,
            DmxFileName = dmxFileName,
            DmxContent = dmx,
            Mapping = report,
            Success = true,
            SolvedFrames = frames,
            Fps = fps,
            Looping = looping,
            ExtractMotion = extractMotion,
            FootstepEvents = events,
            IsMirroredVariant = isMirrored,
            HasAdditiveVariant = deltaName is not null,
            AdditiveVariantName = deltaName,
        });
        var sourceFilename = JoinAssetPath(options.DmxFolderRelative, dmxFileName);
        entries.Add(new AnimEntry
        {
            Name = clipName,
            SourceFilename = sourceFilename,
            Looping = looping,
            ExtractMotion = extractMotion,
            Events = events,
        });
        if (deltaName is not null)
        {
            // The shipped _delta sequences carry the AnimSubtract child and nothing else
            // (no motion extraction, no events) — an additive layer fires no footsteps and
            // extracting root motion from a delta makes no sense.
            entries.Add(new AnimEntry
            {
                Name = deltaName,
                SourceFilename = sourceFilename,
                Looping = looping,
                SubtractAnimName = clipName,
                SubtractFrame = 0,
            });
        }
    }

    /// <summary>
    /// Generates the <c>AE_FOOTSTEP</c> events for a solved clip when the request asks for
    /// them (<see cref="RetargetRequest.GenerateFootstepEvents"/>): plant intervals are
    /// detected on the SOLVED TARGET frames (this is where the engine plays the clip, so
    /// touchdowns must be measured here), each interval start = one footstep
    /// (<see cref="FootstepEvents"/>). Empty when the feature is off or the target rig lacks
    /// the leg chains / character up (noted on the report then).
    /// </summary>
    private static IReadOnlyList<AnimEventEntry> GenerateFootsteps(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        MappingReportInfo report, List<XForm[]> frames, float fps)
    {
        if (!request.GenerateFootstepEvents)
            return Array.Empty<AnimEventEntry>();
        if (context.Up is not { } up || context.FootChains is not { } feet)
        {
            AddNote(report, "Footstep events skipped: " + context.UpOrChainProblem);
            return Array.Empty<AnimEventEntry>();
        }
        return FootstepEvents.Generate(
            frames, target.Rig.Skeleton, feet.Left, feet.Right, up, fps,
            ScaledPlantOptions(target));
    }

    /// <summary>Default plant thresholds are cm-tuned; engine-space rigs are in inches, so
    /// they are scaled by the cm→inch factor to keep the same physical sensitivity (shared by
    /// the foot-plant cleanup and the footstep-event detection).</summary>
    private static FootPlantOptions ScaledPlantOptions(RetargetTargetSpec target)
    {
        var options = new FootPlantOptions();
        if (target.UpAxis == TargetUpAxis.ZUpEngine)
        {
            options.SpeedThresholdCmPerSec *= RetargetTargetSpec.SboxSourceScale;
            options.HeightThresholdCm *= RetargetTargetSpec.SboxSourceScale;
        }
        return options;
    }

    private static bool MapsPinkyRole(MappingResult map)
    {
        foreach (var role in map.RoleToBone.Keys)
        {
            if (role.ToString().StartsWith("Pinky", StringComparison.Ordinal))
                return true;
        }
        return false;
    }

    /// <summary>Solve one take and run the target-space cleanup + IK baking passes.</summary>
    private static Clip SolveAndClean(
        RetargetRequest request, RetargetTargetSpec target, TargetContext context,
        SourceScene scene, MappingResult map, MappingReportInfo report, int take, string clipName)
    {
        var requested = request.Solve ?? new SolveOptions();
        if(request.MocapCorrections is {} wristSettings)
        {
            Motion.WristPositionOffsets.Validate(wristSettings.WristOffsets);
            if(wristSettings.WristOffsets.Any(e=>e.Enabled))
                throw new NotSupportedException("Manual wrist offsets currently require camera-relative hand capture.");
        }
        if(scene.CaptureContacts?.Contacts.Any(c=>c.Review==Motion.ContactReview.Confirmed&&!string.IsNullOrEmpty(c.Object))==true)
            throw new NotSupportedException("Confirmed prop constraints currently require camera-relative hand capture. Disable those constraints to preview body motion; object tracks remain available in captured-skeleton export.");
        var captureClavicleDirections = scene.CaptureSpace is not null && requested.TransferModes is null;
        if (captureClavicleDirections)
        {
            // Body-model collar joints are not the target's anatomical rest carriage.
            // SMPL's zero-pose collar->shoulder slopes upward; its reconstructed neutral
            // pose rotates that line down to level. Replaying the same delta onto the
            // Human's already-level collar line lowers its shoulders a second time.
            AddNote(report, "Full-body capture transfers observed clavicle directions while retaining target bone lengths and attachment positions.");
        }
        var solved = new GeometricSolver().Solve(scene, map, target.Rig, new SolveOptions
        {
            GroundedLegDirections = request.FootPlantCleanup,
            HipScaleHorizontal = requested.HipScaleHorizontal,
            HipScaleVertical = requested.HipScaleVertical,
            TransferFingers = requested.TransferFingers,
            TransferModes = requested.TransferModes,
            CaptureClavicleDirections = captureClavicleDirections,
            NeutralSourceRest = captureClavicleDirections,
            ClipIndex = take,
            ClipName = clipName,
        });
        var frames = solved.Frames;

        // ---- embedded-take fidelity: authored local translations pass through ----------
        if (request.PreserveSourceTranslations)
            PassThroughSourceTranslations(scene, target.Rig, frames, take, report);

        // ---- foot-plant cleanup (target space; up axis from the TARGET character frame) ----
        if (request.FootPlantCleanup)
        {
            if (context.Up is { } up && context.FootChains is { } feet)
            {
                // Grounded stance alignment first: levels planted soles against the ground
                // (removes the stance offset a non-stance source rest leaves in the solver's
                // rest-relative foot transfer). Plants are detected on the SOURCE clip —
                // source-space candidates; hip-height rescaling can push the solved target trajectories
                // outside the cm-tuned Kovar thresholds. Composes with the position pinning
                // below (this rotates feet about their own joints; the pinning preserves
                // foot world rotations).
                // Reconstructed bodies: restore the performer's stance width on differently
                // proportioned hips before anything is levelled or anchored.
                if(scene.CaptureSpace is not null)
                {
                    var stance=Motion.CaptureStanceProportion.Apply(frames,scene,map,target.Rig,feet.Left,feet.Right);
                    if(stance.Samples>0)AddNote(report,$"Stance proportion: each foot moved {stance.HalfWidthCorrection:F2} target units toward the body's centre line, because this target's hip joints are wider relative to its legs than the performer's. Leg lengths and foot orientation are preserved.");
                }
                GroundAlignFeet(frames, scene, map, target.Rig.Skeleton, feet, up, solved.Fps, take);

                var plantOptions=ScaledPlantOptions(target);
                // Reconstructed contacts can be unreachable on different proportions.
                // Keep captured target limb lengths fixed instead of stretching to a guess.
                if(scene.CaptureSpace is not null)plantOptions.MaxStretch=0f;
                FootPlant.Apply(
                    frames, target.Rig.Skeleton, feet.Left, feet.Right, up, solved.Fps,
                    plantOptions);

                // Support ground alignment: one constant vertical offset per clip that
                // restores the SOURCE-authored foot-to-ground relationship (southpaw
                // final regeneration package, gate4_review.md 3.1 / DEFERRED.md f2).
                AlignSupportToGround(frames, scene, map, target.Rig, feet, up, report, take);
                MatchSourceFootHeights(frames, scene, map, target.Rig, feet, up, take);
            }
            else
            {
                AddNote(report, "Foot-plant cleanup skipped: " + context.UpOrChainProblem);
            }
        }

        // A reconstructed body has no finger tracks; give its hands a resting shape, not the bind pose.
        if(scene.CaptureSpace is not null)
        {
            if(Motion.CaptureSpineSpread.Apply(frames,target.Rig)>0)AddNote(report,"Spine: each frame's bend from the hips to the chest is shared evenly between the spine bones; the network puts most of it in the lowest one. Chest, head and arms are unchanged.");
            var shoulders=Motion.CaptureShoulderCarriage.Apply(frames,scene.Clips[take].Frames,scene.Skeleton,map,target.Rig);
            if(shoulders>0)AddNote(report,$"Shoulders: {shoulders} clavicle samples carry the performer's change from their own rest shoulder line onto this target's rest shoulder line, instead of copying a differently built clavicle's direction. Arms keep their solved orientation.");
            // After the shoulders are placed: restore the performer's hand spacing on differently proportioned shoulders.
            var arms=Motion.CaptureArmProportion.Apply(frames,scene.Skeleton,map,target.Rig);
            if(arms.Samples>0)AddNote(report,$"Hand spacing: wrists in front of or across the body moved up to {arms.HalfWidthCorrection:F2} target units toward the centre line, because this target's shoulders are wider relative to its arms than the performer's. Arm lengths and hand orientation are preserved; outstretched arms are left alone.");
            var together=Motion.CaptureHandRelation.Apply(frames,scene.Clips[take].Frames,scene.Skeleton,map,target.Rig);
            if(together>0)AddNote(report,$"Hands together: in {together} frames the performer's hands were close (crossing, clapping or touching) and the character's hands were placed the same way from each other, scaled to its arms.");
            var relaxed=Motion.RelaxedHands.Apply(frames,map,target.Rig);
            if(relaxed>0)AddNote(report,$"Hands: this body capture has no finger tracks, so {relaxed} target finger joints hold one authored, slightly curled resting pose instead of the bind pose. It is not captured finger motion.");
        }

        // ---- optional arm effector IK (default off: the solver already matches anatomical
        // directions; arm IK is only for reach-critical work) ----
        if (request.ArmEffectorIk)
        {
            var problem = ArmIkCleanup.Apply(frames, scene, map, target.Rig, context, take);
            if (problem is not null)
                AddNote(report, "Arm effector IK skipped: " + problem);
        }

        // ---- root motion (see class remarks for the Extract ↔ ExtractMotion mapping) ----
        if(request.FootPlantCleanup&&(request.MocapCorrections?.StabilizeFeet??true))
        {
            var anchored=Motion.CaptureContactRoot.Apply(frames,scene,map,target.Rig,target.UpAxis);
            if(anchored>0)AddNote(report,FormattableString.Invariant($"Travel from contacts: planted feet no longer slide; the body's travel was corrected by up to {anchored:F0} cm to match them."));
            var locking=Motion.CaptureFootLock.Apply(frames,scene,map,target.Rig,target.UpAxis);
            if(locking.ConstrainedSamples>0)AddNote(report,$"Final target foot anchors: {locking.ConstrainedSamples} leg samples; maximum reach residual {locking.MaximumReachResidual:F4} target units; level-floor height drift of up to {locking.MaximumFloorDrift:F2} target units removed from the root. Backend static probabilities are contact suggestions, not measured ground truth.");
            // Keep the whole clip on the floor, including camera-relative captures and dance with few plants.
            if(scene.CaptureSpace is not null)
            {
                var contactMask=Motion.CaptureContactRoot.ContactMask(frames,scene,map,target.Rig,target.UpAxis);
                var grounded=Motion.CaptureGround.Apply(frames,target.Rig,target.UpAxis,solved.Fps,contactMask);
                if(grounded>0)AddNote(report,FormattableString.Invariant($"Floor followed through the clip: up to {grounded:F1} cm of drift toward or away from the floor removed."));
                var hovering=Motion.CaptureHover.Apply(frames,target.Rig,target.UpAxis,solved.Fps,contactMask);
                if(hovering>0)AddNote(report,$"Kept on the floor in {hovering} frames: brief hovering above it or sinking into it removed.");
                var seatedFrames=Motion.CaptureSeat.Apply(frames,scene,map,target.Rig,target.UpAxis);
                if(seatedFrames>0)AddNote(report,$"Seated on the floor in {seatedFrames} frames: hips lowered onto the floor, feet and resting hands held in place.");
                var handsHeld=Motion.CaptureHandPlant.Apply(frames,target.Rig,target.UpAxis,solved.Fps,PlantedHands(scene,map,frames.Count),HandSpread(scene,map,take));
                if(handsHeld>0)AddNote(report,$"Hands on the floor held in place in {handsHeld} hand samples: palms resting on the floor no longer slide or hover.");
            }
        }
        // Last of the leg work: no thigh, shin or foot turns far more in one frame than around it.
        if(scene.CaptureSpace is not null&&Motion.CaptureLegSnaps.Apply(frames,target.Rig,solved.Fps,target.UpAxis==TargetUpAxis.ZUpEngine?39.3700787f:100f,PlantedFeet(scene,map,frames.Count)) is var snaps&&snaps>0)
            AddNote(report,$"Leg continuity corrected in {snaps} samples: isolated rotation or knee-position jolts were spread over neighbouring frames, preserving foot anchors where the constraints allowed.");
        ApplyRootMotion(request.RootMotion, frames, context, report);

        if (request.MocapCorrections is { } corrections)
        {
            Motion.TargetCorrections.Apply(frames, target.Rig, target.UpAxis, corrections);
            if (corrections.FirstPerson) AddNote(report, "Shoulders and elbows are generated target-rig IK, not measured joints.");
        }

        if (scene.CaptureSpace is not null)
        {
            var clearance = Motion.CaptureArmClearance.Apply(frames, scene.Clips[take].Frames, scene.Skeleton, map,
                target.Rig, solved.Fps, out var unresolvedContacts, out var maximumPenetration);
            if (clearance.Samples > 0)
                AddNote(report, FormattableString.Invariant($"Torso contact: DigitalRune CCD adjusted {clearance.Samples} hand samples by up to {clearance.Largest:F2} target units, preserving wrist attitude and finger articulation. Clearance uses a bone-derived body proxy."));
            if (unresolvedContacts > 0)
                AddNote(report, FormattableString.Invariant($"Torso contact remains unresolved in {unresolvedContacts} hand samples (up to {maximumPenetration:F3} target units). Fixed arm lengths and wrist attitude prevented a clear proxy pose; review these contacts."));
        }

        // Last of the pose cleanup: whatever snap a step above left (an IK flip, a contact pushed clear, a hold handed
        // over) is pulled back onto its neighbours' path, keeping planted hands and feet where they are.
        if (scene.CaptureSpace is not null && Motion.CaptureDespike.Apply(frames, target.Rig, target.UpAxis == TargetUpAxis.ZUpEngine ? 1 / 2.54f : 1f) is var smoothedSnaps && smoothedSnaps > 0)
            AddNote(report, $"Snaps removed after cleanup: {smoothedSnaps} joint samples that left the smooth path through their neighbours were pulled back onto it.");

        // ---- IK helper bones (root_IK, IK targets, ikrule) need real baked channels ----
        if (context.HasIkBakedBones)
            IkBoneBaker.Bake(frames, target.Rig);

        // ---- unmapped limb twist bones follow their joint's roll ------------------------
        // Mocap exports a portable baked armature, so it cannot rely on the target
        // model's runtime constraints. Its preview overrides those helpers too.
        // Keep runtime-owned helpers only for the ordinary model-constraint path.
        var twistCount = TwistBoneFollow.Apply(frames, target.Rig,
            request.MocapCorrections is null && target.Rig.HelpersAreConstraintDriven ? context.ConstraintDrivenBones : null);
        if (twistCount > 0)
            AddNote(report, $"{twistCount} limb deform helper bone(s) follow their "
                + "neighboring joints (left at rest they pinch or candy-wrap the skin).");

        // ---- orphan helper bones ride the hips (LAST: anchored to the FINAL hips, after
        // foot-plant pinning / root motion have settled the trajectory) -------------------
        FollowHipsWithOrphanBones(target.Rig, frames, report);

        var looping = request.LoopingOverride ?? solved.Looping;
        return new Clip(clipName, solved.Fps, looping, frames);
    }

    /// <summary>Per source frame, how far apart the performer's hands are across the floor, in shoulder widths; null when the
    /// source lacks hands or shoulders. The capture is Y-up.</summary>
    static float[] HandSpread(SourceScene scene,MappingResult map,int take)
    {
        if(!map.RoleToBone.TryGetValue(BoneRole.HandL,out var handL)||!map.RoleToBone.TryGetValue(BoneRole.HandR,out var handR)
            ||!map.RoleToBone.TryGetValue(BoneRole.UpperArmL,out var armL)||!map.RoleToBone.TryGetValue(BoneRole.UpperArmR,out var armR))return null;
        var source=scene.Clips[take].Frames;var world=new XForm[scene.Skeleton.Count];var spread=new float[source.Count];
        for(var f=0;f<source.Count;f++)
        {
            FkUtil.ToWorld(source[f],scene.Skeleton,world);
            var apart=world[handL].Pos-world[handR].Pos;apart.Y=0;
            var shoulders=Vector3.Distance(world[armL].Pos,world[armR].Pos);
            spread[f]=shoulders>1e-6f?apart.Length()/shoulders:0;
        }
        return spread;
    }

    /// <summary>Frames where the capture marks each hand on the floor (stationary probability at least one half).</summary>
    static Dictionary<BoneRole,bool[]> PlantedHands(SourceScene scene,MappingResult map,int count)
        =>new[]{BoneRole.HandL,BoneRole.HandR}.ToDictionary(role=>role,role=>
        {
            var result=new bool[count];
            if(map.RoleToBone.TryGetValue(role,out var bone)&&scene.CaptureStationaryJoints?.TryGetValue(scene.Skeleton[bone].Name,out var p)==true&&p.Length==count)
                for(var f=0;f<count;f++)result[f]=p[f]>=.5f;
            return result;
        });

    /// <summary>Frames where the capture marks each joint planted (stationary probability at least one half): left ankle, left
    /// toe, right ankle, right toe.</summary>
    static bool[][] PlantedFeet(SourceScene scene,MappingResult map,int count)
        =>new[]{BoneRole.FootL,BoneRole.ToeL,BoneRole.FootR,BoneRole.ToeR}.Select(role=>
        {
            var result=new bool[count];
            if(map.RoleToBone.TryGetValue(role,out var bone)&&scene.CaptureStationaryJoints?.TryGetValue(scene.Skeleton[bone].Name,out var p)==true&&p.Length==count)
                for(var f=0;f<count;f++)result[f]=p[f]>=.5f;
            return result;
        }).ToArray();

    /// <summary>
    /// Unmapped bone subtrees OUTSIDE the mapped skeleton (no mapped ancestor — cloth and
    /// physics helpers parented to the scene root; real case: a skirt of 48 kilt bones on
    /// a Sketchfab catgirl, siblings of the body root) ride the character rigidly. Left
    /// at their rest locals they freeze at the bind spot while the body animates away
    /// ("one part of the body doesn't move at all") and the mesh skinned across the
    /// boundary shears ("completely stretched"). Each subtree's topmost bone anchors to
    /// the HIPS — or to an extremity (hand/foot/head) when its rest sits clearly closer
    /// to it (a sword resting in the hand follows the hand, not the pelvis). Descendants
    /// ride along on their rest locals; bones on the hips' own ancestor path stay
    /// solver-owned (trajectory). A mapped body branch on a separate control tree is
    /// similarly anchored to the nearest hips-connected mapped joint; its solved rotation
    /// remains unchanged.
    /// </summary>
    private static void FollowHipsWithOrphanBones(
        TargetRig rig, List<XForm[]> frames, MappingReportInfo report)
    {
        var skeleton = rig.Skeleton;
        if (rig.BoneForRole(BoneRole.Hips) is not { } hips || frames.Count == 0)
            return;

        var hipsPath = new HashSet<int>();
        for (var b = hips; b >= 0; b = skeleton[b].ParentIndex)
            hipsPath.Add(b);

        bool HasMappedAncestor(int bone)
        {
            for (var b = skeleton[bone].ParentIndex; b >= 0; b = skeleton[b].ParentIndex)
            {
                if (rig.RoleOf(b) is not null)
                    return true;
            }
            return false;
        }

        var rest = skeleton.RestWorld;

        bool DescendsFrom(int bone, int ancestor)
        {
            for (var b = bone; b >= 0; b = skeleton[b].ParentIndex)
                if (b == ancestor)
                    return true;
            return false;
        }

        // Extremity anchors: adopted only when the orphan rests at less than half its
        // hips distance — near-torso helpers (skirts, tails, capes) stay on the hips,
        // which never mistakes a skirt panel brushing a thigh for hand luggage.
        var extremities = new List<int>();
        foreach (var role in new[]
        {
            BoneRole.HandL, BoneRole.HandR, BoneRole.FootL, BoneRole.FootR, BoneRole.Head,
        })
        {
            if (rig.BoneForRole(role) is { } bone)
                extremities.Add(bone);
        }

        // Topmost orphans: unmapped, off the hips' ancestor path, no mapped ancestor,
        // and the parent is either the scene root path or absent (children of deeper
        // orphans ride along unchanged).
        var tops = new List<(int Bone, int Anchor)>();
        for (var i = 0; i < skeleton.Count; i++)
        {
            if (rig.RoleOf(i) is not null || hipsPath.Contains(i) || HasMappedAncestor(i))
                continue;
            var parent = skeleton[i].ParentIndex;
            if (parent >= 0 && !hipsPath.Contains(parent))
                continue;

            var anchor = hips;
            var hipsDistance = (rest[i].Pos - rest[hips].Pos).Length();
            var best = hipsDistance * 0.5f;
            foreach (var candidate in extremities)
            {
                var distance = (rest[i].Pos - rest[candidate].Pos).Length();
                if (distance < best)
                {
                    best = distance;
                    anchor = candidate;
                }
            }
            tops.Add((i, anchor));
        }

        // A few constraint-oriented exports place a real mapped body branch on a parallel
        // control hierarchy. The common case is a skinned head under CONTROL_NECK while
        // the deform cervical chain is under the hips. glTF/FBX does not preserve the DCC
        // constraint that joined those trees, so rotations solve but the branch stays at
        // its bind position. Anchor each topmost detached mapped branch to the nearest
        // mapped joint that really descends from the hips, preserving its solved rotation.
        var connectedMapped = Enumerable.Range(0, skeleton.Count)
            .Where(i => rig.RoleOf(i) is not null && DescendsFrom(i, hips))
            .ToList();
        var detachedMapped = new List<(int Bone, int Anchor)>();
        for (var i = 0; i < skeleton.Count; i++)
        {
            if (rig.RoleOf(i) is null || hipsPath.Contains(i) || DescendsFrom(i, hips)
                || HasMappedAncestor(i) || connectedMapped.Count == 0)
                continue;
            var anchor = connectedMapped
                .OrderBy(candidate => (rest[i].Pos - rest[candidate].Pos).LengthSquared())
                .First();
            detachedMapped.Add((i, anchor));
        }

        // A detached deform head may retain a small control-space bind pitch after the DCC
        // constraint is lost. Infer its gaze only when one local axis already agrees closely
        // with character-forward, then remove the small vertical component. Applying the
        // correction in rest-local space preserves every solved animation delta.
        var neutralHead = -1;
        var neutralHeadCorrection = Quaternion.Identity;
        foreach (var (bone, _) in detachedMapped)
        {
            if (rig.RoleOf(bone) == BoneRole.Head
                && TryDetachedHeadNeutralCorrection(rig, bone, out neutralHeadCorrection))
            {
                neutralHead = bone;
                break;
            }
        }

        if (tops.Count == 0 && detachedMapped.Count == 0)
            return;

        var anchorRestInverse = new Dictionary<int, XForm>();
        foreach (var (_, anchor) in tops)
            anchorRestInverse[anchor] = rest[anchor].Inverse();
        foreach (var (_, anchor) in detachedMapped)
            anchorRestInverse[anchor] = rest[anchor].Inverse();

        foreach (var frame in frames)
        {
            var world = new Skeleton.Pose(frame).ToWorld(skeleton);
            foreach (var (top, anchor) in tops)
            {
                var delta = XForm.Compose(world[anchor], anchorRestInverse[anchor]);
                var parent = skeleton[top].ParentIndex;
                var parentWorld = parent >= 0 ? world[parent] : XForm.Identity;
                frame[top] = XForm.ToLocal(
                    parentWorld, XForm.Compose(delta, rest[top]));
            }

            if (detachedMapped.Count == 0)
                continue;

            // Re-evaluate after moving orphan control roots (the detached branch's actual
            // parent may be inside one). Only position is anchored: its mapped rotation is
            // the solver's result and must remain authoritative.
            world = new Skeleton.Pose(frame).ToWorld(skeleton);
            foreach (var (bone, anchor) in detachedMapped)
            {
                var delta = XForm.Compose(world[anchor], anchorRestInverse[anchor]);
                var rotation = bone == neutralHead
                    ? MathQ.Normalize(world[bone].Rot * neutralHeadCorrection)
                    : world[bone].Rot;
                var desired = new XForm(
                    XForm.Compose(delta, rest[bone]).Pos,
                    rotation);
                var parent = skeleton[bone].ParentIndex;
                frame[bone] = parent < 0
                    ? desired
                    : XForm.ToLocal(world[parent], desired);
            }
        }
        if (tops.Count > 0)
            AddNote(report,
                $"{tops.Count} helper bone subtree(s) outside the mapped skeleton ride the "
                + "character (cloth/physics/prop bones would otherwise freeze at their bind position).");
        if (detachedMapped.Count > 0)
            AddNote(report,
                $"{detachedMapped.Count} mapped body branch(es) on separate control hierarchies "
                + "follow the connected skeleton (exported DCC constraints are not available at runtime).");
        if (neutralHead >= 0)
            AddNote(report,
                "Detached head bind pitch was leveled to the character facing plane while preserving animation.");
    }

    private static void MatchSourceFootHeights(
        List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,
        (FootChain Left, FootChain Right) feet, Vector3 up, int take)
    {
        if (frames.Count == 0 || !map.RoleToBone.TryGetValue(BoneRole.Hips, out var srcHips)
            || rig.BoneForRole(BoneRole.Hips) is not int tgtHips)
            return;
        var source = scene.Skeleton;
        var target = rig.Skeleton;
        if (!scene.RestPlacementAuthored && !RestNormalizer.IsAnatomicalRest(source, map, source.RestWorld))
            return; // Bone-length-only rests cannot calibrate an anatomical support height.
        var srcFrames = scene.Clips[take].Frames;
        if (srcFrames.Count != frames.Count)
            return;
        var srcUp = scene.UpAxis switch
        {
            0 => new Vector3(scene.UpAxisSign, 0, 0),
            2 => new Vector3(0, 0, scene.UpAxisSign),
            _ => new Vector3(0, scene.UpAxisSign, 0),
        };
        up = GroundUp(up);
        var worlds = new XForm[frames.Count][];
        var restGround = float.PositiveInfinity;
        var motionGround = float.PositiveInfinity;
        foreach (var rest in source.RestWorld)
            restGround = MathF.Min(restGround, Vector3.Dot(rest.Pos, srcUp));
        for (var f = 0; f < frames.Count; f++)
        {
            worlds[f] = new Skeleton.Pose(srcFrames[f]).ToWorld(source);
            foreach (var bone in worlds[f])
                motionGround = MathF.Min(motionGround, Vector3.Dot(bone.Pos, srcUp));
        }
        var placement = scene.RestPlacementAuthored ? 0f : motionGround - restGround;
        var corrections = new List<(FootChain Chain, Vector3[] Goals)>();
        var lowerPelvis = new float[frames.Count];
        foreach (var (footRole, toeRole, chain) in new[]
        {
            (BoneRole.FootL, BoneRole.ToeL, feet.Left), (BoneRole.FootR, BoneRole.ToeR, feet.Right),
        })
        {
            if (!map.RoleToBone.TryGetValue(footRole, out var foot)
                || !map.RoleToBone.TryGetValue(toeRole, out var toe) || chain.Toe is not int tgtToe)
                continue;
            float Support(IReadOnlyList<XForm> pose, int ankle, int tip, Vector3 vertical)
                => MathF.Min(Vector3.Dot(pose[ankle].Pos, vertical), Vector3.Dot(pose[tip].Pos, vertical));
            var srcRest = Support(source.RestWorld, foot, toe, srcUp);
            var tgtRest = Support(target.RestWorld, chain.Ankle, tgtToe, up);
            // Animation-only FBXs can store a mid-stride rest, with one foot lifted.
            // That raised foot is not a ground reference: subtracting it drives its
            // planted frames below the floor. An authored rest never needs a higher
            // support baseline than the lowest support actually reached by that foot.
            if (scene.RestPlacementAuthored)
                foreach (var pose in worlds)
                    srcRest = MathF.Min(srcRest, Support(pose, foot, toe, srcUp));
            var srcHeight = Vector3.Dot(source.RestWorld[srcHips].Pos, srcUp) - srcRest;
            if (srcHeight <= .001f)
                continue;
            var ratio = Math.Clamp((Vector3.Dot(target.RestWorld[tgtHips].Pos, up) - tgtRest) / srcHeight, .25f, 4f);
            var goals = new Vector3[frames.Count];
            for (var f = 0; f < frames.Count; f++)
            {
                var world = new Skeleton.Pose(frames[f]).ToWorld(target);
                var desired = tgtRest + (Support(worlds[f], foot, toe, srcUp) - srcRest - placement) * ratio;
                goals[f] = world[chain.Ankle].Pos + up * (desired - Support(world, chain.Ankle, tgtToe, up));
                var reach = Vector3.Distance(world[chain.Hip].Pos, world[chain.Knee].Pos)
                    + Vector3.Distance(world[chain.Knee].Pos, world[chain.Ankle].Pos);
                var toHip = world[chain.Hip].Pos - goals[f];
                if (scene.CaptureSpace is not null)
                {
                    lowerPelvis[f] = MathF.Max(lowerPelvis[f], Motion.CaptureLegReach.Lowering(toHip, up, reach));
                    continue;
                }
                var vertical = Vector3.Dot(toHip, up);
                var horizontal = toHip - up * vertical;
                if (horizontal.LengthSquared() < reach * reach)
                    lowerPelvis[f] = MathF.Max(lowerPelvis[f], vertical
                        - MathF.Sqrt(reach * reach - horizontal.LengthSquared()));
            }
            corrections.Add((chain, goals));
        }
        // At full extension, lower the pelvis only as far as needed to reach BOTH
        // contacts. Stretching bones or accepting an unreachable goal leaves a hover.
        for (var f = 0; f < frames.Count; f++)
        {
            if (lowerPelvis[f] <= 0f) continue;
            var parent = target[tgtHips].ParentIndex;
            var shift = -up * lowerPelvis[f];
            if (parent >= 0)
                shift = Vector3.Transform(shift, Quaternion.Conjugate(
                    new Skeleton.Pose(frames[f]).ToWorld(target)[parent].Rot));
            frames[f][tgtHips].Pos += shift;
        }
        foreach (var (chain, goals) in corrections)
        {
            // Vertical IK preserves horizontal travel and foot rotation; it never scales bones.
            EffectorIk.ApplyGoals(frames, target,
                new LimbChain { Upper = chain.Hip, Lower = chain.Knee, End = chain.Ankle },
                goals, ArmIkCleanup.RestBendAxis(target, chain.Hip, chain.Knee, chain.Ankle), soften: 0f);
        }
    }

    private static bool TryDetachedHeadNeutralCorrection(
        TargetRig rig, int head, out Quaternion localCorrection)
    {
        localCorrection = Quaternion.Identity;
        CharacterFrame frame;
        try
        {
            frame = CharacterFrame.Compute(
                rig.Skeleton, rig.ToMappingResult(), rig.Skeleton.RestWorld);
        }
        catch (ArgumentException)
        {
            return false;
        }

        var restRotation = MathQ.Normalize(rig.Skeleton.RestWorld[head].Rot);
        var gaze = Vector3.Zero;
        var agreement = float.NegativeInfinity;
        foreach (var localAxis in new[] { Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ })
        {
            var axis = Vector3.Transform(localAxis, restRotation);
            var dot = Vector3.Dot(axis, frame.Forward);
            if (MathF.Abs(dot) <= agreement)
                continue;
            agreement = MathF.Abs(dot);
            gaze = dot < 0f ? -axis : axis;
        }

        var vertical = Vector3.Dot(gaze, frame.Up);
        const float minAgreement = 0.94f; // local axis must be within 20° of facing
        const float minPitch = 0.5f * MathF.PI / 180f;
        const float maxPitch = 12f * MathF.PI / 180f;
        var pitch = MathF.Asin(Math.Clamp(vertical, -1f, 1f));
        if (agreement < minAgreement || MathF.Abs(pitch) < minPitch || MathF.Abs(pitch) > maxPitch)
            return false;

        var levelGaze = gaze - frame.Up * vertical;
        if (levelGaze.LengthSquared() < 1e-8f)
            return false;
        levelGaze = Vector3.Normalize(levelGaze);

        var worldCorrection = MathQ.FromTo(gaze, levelGaze);
        localCorrection = MathQ.Normalize(
            Quaternion.Conjugate(restRotation) * worldCorrection * restRotation);
        return true;
    }

    /// <summary>
    /// The engine-side yaw correction for embedded meshes and compiled Z-up targets (see
    /// <see cref="EmitClip"/>): the compiler's source-axis conversion for ROOT-LEVEL
    /// animation channels lands 90° about up away from where it puts the mesh bind.
    /// Pre-rotating root locals by the inverse importer yaw (−90° for Y-up,
    /// +90° for Z-up) makes compiled playback match the bind; children are parent-relative.
    /// </summary>
    private static List<XForm[]> CompensateEmbeddedMeshRootYaw(
        IReadOnlyList<XForm[]> frames, TargetRig rig, TargetUpAxis upAxis)
    {
        var yUp = upAxis == TargetUpAxis.YUpCm;
        var axis = yUp ? Vector3.UnitY : Vector3.UnitZ;
        var yaw = Quaternion.CreateFromAxisAngle(axis, (yUp ? -1f : 1f) * MathF.PI * 0.5f);
        var skeleton = rig.Skeleton;
        var result = new List<XForm[]>(frames.Count);
        foreach (var frame in frames)
        {
            var copy = new XForm[frame.Length];
            for (var i = 0; i < frame.Length; i++)
            {
                copy[i] = i < skeleton.Count && skeleton[i].ParentIndex < 0
                    ? new XForm(
                        Vector3.Transform(frame[i].Pos, yaw),
                        MathQ.Normalize(yaw * frame[i].Rot))
                    : frame[i];
            }
            result.Add(copy);
        }
        return result;
    }

    /// <summary>Test seam for <see cref="CompensateEmbeddedMeshRootYaw"/> (gate bisects
    /// re-serialize mutated frames with the same compensation the pipeline applies).</summary>
    public static List<XForm[]> TestHook_CompensateEmbeddedMeshRootYaw(
        IReadOnlyList<XForm[]> frames, RetargetTargetSpec target)
        => !string.IsNullOrEmpty(target.MeshFilePath) || target.UpAxis == TargetUpAxis.ZUpEngine
            ? CompensateEmbeddedMeshRootYaw(frames, target.Rig, target.UpAxis)
            : frames.ToList();

    /// <summary>Test seam for <see cref="FollowHipsWithOrphanBones"/>.</summary>
    public static void TestHook_FollowOrphans(TargetRig rig, List<XForm[]> frames)
        => FollowHipsWithOrphanBones(rig, frames, new MappingReportInfo
        {
            ProfileName = "test",
            Source = MappingSource.Manual,
            Confidence = 1f,
            NeedsUserDecision = false,
            MappedRoleCount = 0,
            SkeletonSignature = "",
        });

    /// <summary>
    /// <see cref="RetargetRequest.PreserveSourceTranslations"/>: per-frame source local
    /// translations onto same-named target bones. Names are compared engine-sanitized
    /// (non-alphanumerics → <c>_</c>: the compiled-model rig the editor rebuilds carries
    /// <c>Bip01_R_Hand</c> for the file's <c>Bip01 R Hand</c>). A matched bone whose REST
    /// translation disagrees between the rigs is skipped — the name collision is then
    /// coincidence, not the same joint. The hips and its ancestors always stay
    /// solver-owned (trajectory, root-motion modes, hip rescale).
    /// </summary>
    private static void PassThroughSourceTranslations(
        SourceScene scene, TargetRig rig, List<XForm[]> frames, int take,
        MappingReportInfo report)
    {
        var src = scene.Skeleton;
        var tgt = rig.Skeleton;
        var srcClip = scene.Clips[take];
        if (srcClip.Frames.Count != frames.Count)
        {
            AddNote(report, "Source translations not preserved: frame counts differ "
                + $"({srcClip.Frames.Count} source vs {frames.Count} solved).");
            return;
        }

        static string Key(string name)
        {
            Span<char> c = stackalloc char[name.Length];
            for (var i = 0; i < name.Length; i++)
                c[i] = char.IsLetterOrDigit(name[i]) ? char.ToLowerInvariant(name[i]) : '_';
            return new string(c);
        }

        var srcByName = new Dictionary<string, int>();
        for (var i = 0; i < src.Count; i++)
        {
            // Duplicate keys are ambiguous - poison them rather than guess.
            var key = Key(src[i].Name);
            srcByName[key] = srcByName.ContainsKey(key) ? -1 : i;
        }

        var excluded = new HashSet<int>();
        if (rig.BoneForRole(BoneRole.Hips) is { } hips)
            for (var b = hips; b >= 0; b = tgt[b].ParentIndex)
                excluded.Add(b);

        var applied = 0;
        for (var t = 0; t < tgt.Count; t++)
        {
            if (excluded.Contains(t)
                || !srcByName.TryGetValue(Key(tgt[t].Name), out var s) || s < 0)
                continue;
            // Same joint check: rest translations must agree (same rig, same space).
            var restDelta = (src[s].RestLocal.Pos - tgt[t].RestLocal.Pos).Length();
            if (restDelta > MathF.Max(1f, 0.1f * tgt[t].RestLocal.Pos.Length()))
                continue;
            for (var f = 0; f < frames.Count; f++)
                frames[f][t] = new XForm(srcClip.Frames[f][s].Pos, frames[f][t].Rot);
            applied++;
        }
        if (applied > 0)
            AddNote(report, $"Embedded take: authored local translations preserved on {applied} bones.");
    }

    /// <summary>
    /// Normalized-rest foot pitch beyond which (toe approaching/above ankle level) the rest
    /// cannot be a flat stance — measured stance rests sit at −11°…−51°; the repro artifact
    /// rig measured +2.7° on one foot.
    /// </summary>
    private const float StancePitchMaxDeg = -5f;

    /// <summary>Left/right normalized-rest foot pitch asymmetry beyond which the rest is not
    /// a (symmetric) stance — measured stance rests differ ≤ 2.4°; the repro artifact rig
    /// 13.8°.</summary>
    private const float StancePitchAsymmetryDeg = 6f;

    /// <summary>
    /// The grounded-foot stance recalibration step (<see cref="FootGroundAlign"/>). Runs ONLY
    /// when the source's NORMALIZED rest — the solver's delta reference — is implausible as a
    /// flat stance (a foot's toe at/above ankle level, or the two feet resting asymmetrically;
    /// both measured on the repro rig, where T-pose normalization of a bent-leg rest swings
    /// the feet 14–26° away from the rig's true stance). On plausible stance rests the solver's
    /// rest-relative foot transfer is already faithful, and planted-sole deviations are
    /// genuine articulation (boxing stances, heel rolls) that must NOT be flattened. Plant
    /// intervals are detected on the SOURCE clip (cm space, default Kovar thresholds).
    /// Best-effort — silently skipped when the source maps no complete leg chains + toes or a
    /// character frame is not computable (the foot transfer is then simply left as solved).
    /// </summary>
    private static void GroundAlignFeet(
        List<XForm[]> frames, SourceScene scene, MappingResult map, SkeletonModel targetSkeleton,
        (FootChain Left, FootChain Right) targetFeet, Vector3 targetUp, float fps, int take)
    {
        FootChain? SourceChain(BoneRole upper, BoneRole lower, BoneRole foot, BoneRole toe)
            => map.RoleToBone.TryGetValue(upper, out var hip)
               && map.RoleToBone.TryGetValue(lower, out var knee)
               && map.RoleToBone.TryGetValue(foot, out var ankle)
                ? new FootChain
                {
                    Hip = hip,
                    Knee = knee,
                    Ankle = ankle,
                    Toe = map.RoleToBone.TryGetValue(toe, out var t) ? t : null,
                }
                : null;

        var srcLeft = SourceChain(BoneRole.UpperLegL, BoneRole.LowerLegL, BoneRole.FootL, BoneRole.ToeL);
        var srcRight = SourceChain(BoneRole.UpperLegR, BoneRole.LowerLegR, BoneRole.FootR, BoneRole.ToeR);
        if (srcLeft?.Toe is not int srcToeL || srcRight?.Toe is not int srcToeR)
            return; // toe-less sources take the solver's virtual-foot fallback instead

        // ---- rest-stance plausibility (normalized rest, the solver's delta reference) ----
        float pitchL, pitchR;
        Vector3 srcUp;
        try
        {
            var (srcNorm, _) = RestNormalizer.Normalize(scene.Skeleton, map);
            var srcCanon = CanonicalFrames.Build(scene.Skeleton, map, srcNorm.WorldRest);
            srcUp = Vector3.Normalize(srcCanon.CharacterUp);

            float RestPitchDeg(int foot, int toe)
            {
                var dir = srcNorm.WorldRest[toe].Pos - srcNorm.WorldRest[foot].Pos;
                if (dir.LengthSquared() < 1e-8f)
                    return 0f;
                var s = Vector3.Dot(Vector3.Normalize(dir), srcUp);
                return MathF.Asin(Math.Clamp(s, -1f, 1f)) * (180f / MathF.PI);
            }

            pitchL = RestPitchDeg(srcLeft.Ankle, srcToeL);
            pitchR = RestPitchDeg(srcRight.Ankle, srcToeR);
        }
        catch (ArgumentException)
        {
            return;
        }

        var restIsStance = pitchL < StancePitchMaxDeg && pitchR < StancePitchMaxDeg
            && MathF.Abs(pitchL - pitchR) <= StancePitchAsymmetryDeg;
        if (restIsStance)
            return;

        var srcFrames = scene.Clips[take].Frames;
        var (plantsL, plantsR) = FootPlant.DetectPlantIntervals(
            srcFrames, scene.Skeleton, srcLeft, srcRight, srcUp, fps);
        if (plantsL.Count == 0 && plantsR.Count == 0)
            return;

        FootGroundAlign.Apply(
            frames, targetSkeleton, targetFeet.Left, targetFeet.Right, targetUp,
            plantsL, plantsR);
    }

    /// <summary>
    /// Restores the clip's SOURCE-authored foot-to-ground relationship with ONE constant
    /// vertical offset per clip (southpaw final regeneration package: DEFERRED.md f2 and
    /// gate4_review.md 3.1). The solver's vertical reference is the source REST pelvis;
    /// mid-pose exports whose kept node rest erased the authored crouch leave every solved
    /// frame hovering by exactly the erased crouch depth (measured: stance +5.9 cm, steps
    /// +7.8 to +10.3, slips ~+9, while the source FBX is grounded everywhere). Fix, the
    /// generalization of the BVH ClipPlacementOffset vertical logic to every source: measure
    /// the clip's minimum foot support (ankles + toes) in the SOLVED target frames and shift
    /// the whole clip vertically so that support equals the TARGET rest support plus the
    /// source clip's own authored support delta (source clip support minus source rest
    /// support, hip-height scaled). One constant per clip preserves every within-clip lift,
    /// heel raise and step cycle exactly: authored articulation is never flattened and an
    /// authored jump stays airborne (its source support delta rides along).
    /// </summary>
    private static void AlignSupportToGround(
        List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,
        (FootChain Left, FootChain Right) feet, Vector3 up, MappingReportInfo report, int take)
    {
        if (frames.Count == 0)
            return;
        var skeleton = rig.Skeleton;
        var rest = skeleton.RestWorld;
        var srcClip = scene.Clips[take];
        var src = scene.Skeleton;

        // The GROUND normal is the rig-space vertical axis, not the character-lean up:
        // the character frame's up tilts a few degrees with the rest posture, and a
        // tilted dot-metric slants the ground line across a traveling clip (measured:
        // 28 cm of false offset on a long corpus walk). Snap to the dominant axis.
        up = GroundUp(up);

        // ---- support-bone set: the roles mapped on BOTH rigs (metrics must compare
        // the same anatomical points or anthropometric offsets leak into the gap) ----
        var supportRoles = new List<BoneRole>();
        foreach (var role in new[] { BoneRole.FootL, BoneRole.FootR, BoneRole.ToeL, BoneRole.ToeR })
        {
            if (map.RoleToBone.ContainsKey(role) && rig.BoneForRole(role) is not null)
                supportRoles.Add(role);
        }
        var sourceMeasured = supportRoles.Contains(BoneRole.FootL) && supportRoles.Contains(BoneRole.FootR)
            && srcClip.Frames.Count > 0 && srcClip.Frames[0].Length == src.Count;
        if (!sourceMeasured)
        {
            // No reliable common support metric: fall back to the ankles the target
            // chains provide and a zero source gap (best guess: grounded).
            supportRoles.Clear();
        }

        var tgtSupportBones = new List<int>();
        foreach (var role in supportRoles)
            tgtSupportBones.Add(rig.BoneForRole(role)!.Value);
        if (tgtSupportBones.Count == 0)
        {
            tgtSupportBones.Add(feet.Left.Ankle);
            tgtSupportBones.Add(feet.Right.Ankle);
        }

        var tgtRestSupport = float.MaxValue;
        foreach (var b in tgtSupportBones)
            tgtRestSupport = MathF.Min(tgtRestSupport, Vector3.Dot(rest[b].Pos, up));

        var solvedSupport = float.MaxValue;
        foreach (var frame in frames)
        {
            var world = new Skeleton.Pose(frame).ToWorld(skeleton);
            foreach (var b in tgtSupportBones)
                solvedSupport = MathF.Min(solvedSupport, Vector3.Dot(world[b].Pos, up));
        }

        // ---- source-authored support gap --------------------------------------
        float sourceRel = 0f;
        if (sourceMeasured)
        {
            var srcSupportBones = new List<int>();
            foreach (var role in supportRoles)
                srcSupportBones.Add(map.RoleToBone[role]);

            var srcUp = scene.UpAxis switch
            {
                0 => new Vector3(scene.UpAxisSign, 0f, 0f),
                2 => new Vector3(0f, 0f, scene.UpAxisSign),
                _ => new Vector3(0f, scene.UpAxisSign, 0f),
            };
            var srcHips = map.RoleToBone.TryGetValue(BoneRole.Hips, out var sh) ? sh : -1;

            var srcRestSupport = float.MaxValue;
            var srcRestGround = float.MaxValue;
            for (var b = 0; b < src.Count; b++)
            {
                var h = Vector3.Dot(src.RestWorld[b].Pos, srcUp);
                srcRestGround = MathF.Min(srcRestGround, h);
            }
            foreach (var b in srcSupportBones)
                srcRestSupport = MathF.Min(srcRestSupport, Vector3.Dot(src.RestWorld[b].Pos, srcUp));

            var srcClipSupport = float.MaxValue;
            var srcMotionGround = float.MaxValue;
            foreach (var frame in srcClip.Frames)
            {
                var world = new Skeleton.Pose(frame).ToWorld(src);
                foreach (var b in srcSupportBones)
                    srcClipSupport = MathF.Min(srcClipSupport, Vector3.Dot(world[b].Pos, srcUp));
                if (!scene.RestPlacementAuthored)
                {
                    for (var b = 0; b < src.Count; b++)
                        srcMotionGround = MathF.Min(srcMotionGround, Vector3.Dot(world[b].Pos, srcUp));
                }
            }

            // AUTHORED placements (FBX): the rest stands on the authored ground, so the
            // gap is simply clip support minus rest support (same bones, same space).
            // UN-PLACED sources (BVH capture volumes): absolute placement is meaningless,
            // so both terms go placement-free: the clip's support above its OWN motion
            // ground (lowest joint anywhere, incl. static origin markers) compared to the
            // rest pose's support above ITS lowest joint. A grounded walk reads ~0, a
            // jump reads its true airborne height, a crawl reads its raised feet.
            float gap;
            if (scene.RestPlacementAuthored)
                gap = srcClipSupport - srcRestSupport;
            else
                gap = (srcClipSupport - srcMotionGround) - (srcRestSupport - srcRestGround);

            // Hip-height ratio scales the (small) source gap into target units,
            // clamped against degenerate rest measurements.
            var ratio = 1f;
            if (srcHips >= 0 && rig.BoneForRole(BoneRole.Hips) is { } tgtHips)
            {
                var srcHipHeight = Vector3.Dot(src.RestWorld[srcHips].Pos, srcUp) - srcRestSupport;
                var tgtHipHeight = Vector3.Dot(rest[tgtHips].Pos, up) - tgtRestSupport;
                if (srcHipHeight > 1e-3f && float.IsFinite(tgtHipHeight / srcHipHeight))
                    ratio = Math.Clamp(tgtHipHeight / srcHipHeight, 0.25f, 4f);
            }
            sourceRel = gap * ratio;
        }

        var delta = tgtRestSupport + sourceRel - solvedSupport;
        if (!float.IsFinite(delta) || MathF.Abs(delta) > 100f)
        {
            AddNote(report, $"Support ground alignment skipped: implausible offset {delta:0.0}.");
            return;
        }
        if (MathF.Abs(delta) < 0.01f)
            return; // already aligned

        var shift = up * delta;
        foreach (var frame in frames)
        {
            for (var i = 0; i < skeleton.Count; i++)
            {
                if (skeleton[i].ParentIndex < 0)
                    frame[i] = new XForm(frame[i].Pos + shift, frame[i].Rot);
            }
        }
        AddNote(report, sourceMeasured
            ? $"Support ground alignment: {delta:0.00} vertical offset applied "
              + $"(source-authored support delta {sourceRel:0.00})."
            : $"Support ground alignment: {delta:0.00} vertical offset applied "
              + "(source feet unmapped; clip support aligned to target rest support).");
    }

    private static Vector3 GroundUp(Vector3 up)
    {
        var absolute = Vector3.Abs(up);
        return absolute.X >= absolute.Y && absolute.X >= absolute.Z
            ? new Vector3(MathF.Sign(up.X), 0, 0)
            : absolute.Y >= absolute.Z
                ? new Vector3(0, MathF.Sign(up.Y), 0)
                : new Vector3(0, 0, MathF.Sign(up.Z));
    }

    private static void ApplyRootMotion(
        RootMotionMode mode, List<XForm[]> frames, TargetContext context, MappingReportInfo report)
    {
        if (mode == RootMotionMode.Off)
            return;

        if (context.HipsIndex is not { } hips)
        {
            AddNote(report, $"Root motion ({mode}) skipped: target rig maps no Hips role.");
            return;
        }
        if (context.Up is not { } up)
        {
            AddNote(report, $"Root motion ({mode}) skipped: {context.UpOrChainProblem}");
            return;
        }

        if (mode == RootMotionMode.Extract && context.DedicatedRootIndex is null)
        {
            // s&box-style target: pelvis is parentless and there is no separate translating
            // root bone (root_IK is IkBaked). Bone-level extraction is impossible — the vmdl
            // AnimFile entry carries an ExtractMotion node instead (compile-time extraction).
            AddNote(report,
                "Root-motion extract: target has no dedicated animated root bone distinct from "
                + "the hips; frames left as solved and motion extraction delegated to the vmdl "
                + "AnimFile ExtractMotion node.");
            return;
        }

        var root = context.DedicatedRootIndex ?? hips;
        var worldUp = GroundUp(up);
        // Skeleton-aware overload: hips world via real parent-chain FK, locals re-derived
        // against the actual parent (HipsParentIsRoot is ignored by this overload).
        RootMotion.Apply(frames, context.Rig.Skeleton, new RootMotionAxes
        {
            // Match the world vertical used by support-height cleanup. A slightly
            // leaning target torso must not tilt the plane used to remove travel;
            // otherwise this final pass reintroduces vertical drift into grounded feet.
            Up = worldUp,
            RootIndex = root,
            HipsIndex = hips,
            HipsParentIsRoot = context.HipsParentIsRoot,
        }, mode);
        if (mode == RootMotionMode.InPlace && frames.Count > 0)
        {
            // Animation-only files may start far from their static reference pose.
            // Removing travel alone freezes that offset into the clip, so blending
            // directions moves the mesh away from its controller. Center every clip
            // on the target bind hips, preserving vertical motion and local rotations.
            var skeleton = context.Rig.Skeleton;
            var center = Vector3.Zero;
            foreach (var frame in frames)
                center += FkUtil.BoneWorld(frame, skeleton, hips).Pos;
            var offset = skeleton.RestWorld[hips].Pos - center / frames.Count;
            offset -= Vector3.Dot(offset, worldUp) * worldUp;
            foreach (var frame in frames)
                for (var b = 0; b < skeleton.Count; b++)
                    if (skeleton[b].ParentIndex < 0)
                        frame[b] = new XForm(frame[b].Pos + offset, frame[b].Rot);
        }
        AddNote(report, mode == RootMotionMode.Extract
            ? $"Root motion extracted onto dedicated root bone (index {root})."
            : "Root motion removed (in-place clip).");
    }

    private static void AddNote(MappingReportInfo report, string note)
    {
        if (!report.Notes.Contains(note))
            report.Notes.Add(note);
    }

    /// <summary>
    /// Mid-pose FBX sources: adopts the importer's bind-rest alternate skeleton when it
    /// makes the character stand STRAIGHTER along the file's own up axis. Solving on a
    /// posed rest breaks the solver's anatomical reasoning on exactly the posed limbs
    /// (measured 48° mean world-rot off ground truth on a real rig, left foot 124°); but
    /// a bind rest can also tilt the character-up estimate (shoulders behind hips on one
    /// real rig tilted it 7°, starving plant/stance detection), so the straighter rest
    /// wins. Clips are authored playback either way — same bones, same order.
    /// </summary>
    private static SourceScene MaybeAdoptBindRest(
        SourceScene scene, MappingResult map, MappingReportInfo report)
    {
        if (scene.MidPoseBindSkeleton is not { } bindSkeleton)
            return scene;

        var fileUp = scene.UpAxis switch
        {
            0 => new Vector3(scene.UpAxisSign, 0, 0),
            2 => new Vector3(0, 0, scene.UpAxisSign),
            _ => new Vector3(0, scene.UpAxisSign, 0),
        };

        float UpTiltDeg(SkeletonModel skeleton)
        {
            var (norm, _) = RestNormalizer.Normalize(skeleton, map);
            var up = Vector3.Normalize(
                CanonicalFrames.Build(skeleton, map, norm.WorldRest).CharacterUp);
            return MathF.Acos(Math.Clamp(Vector3.Dot(up, fileUp), -1f, 1f)) * 180f / MathF.PI;
        }

        try
        {
            float tiltStatics = UpTiltDeg(scene.Skeleton);
            float tiltBind = UpTiltDeg(bindSkeleton);
            if (tiltBind > tiltStatics + 1f)
            {
                AddNote(report,
                    $"mid-pose export: kept the exported pose as rest - the file's bind "
                    + $"data stands {tiltBind:0.#} deg off the file up axis "
                    + $"(vs {tiltStatics:0.#} deg)");
                return scene;
            }

            AddNote(report,
                "mid-pose export: rest pose restored from the file's own bind data "
                + "(clips keep their authored playback)");
            return new SourceScene(
                bindSkeleton, scene.Clips, scene.UnitScaleCm,
                scene.UpAxis, scene.UpAxisSign,
                scene.FrontAxis, scene.FrontAxisSign,
                scene.CoordAxis, scene.CoordAxisSign,
                scene.OriginalUpAxis, scene.Notes)
            {
                AuthoredMapping = scene.AuthoredMapping,
                RestPlacementAuthored = scene.RestPlacementAuthored,
            };
        }
        catch (Exception)
        {
            // Anatomy not measurable (mapping lacks the frame's roles, degenerate rest):
            // keep today's behavior.
            return scene;
        }
    }

    // ================================================================ import + mapping

    /// <summary>
    /// Imports source-file bytes exactly like conversion does: the extension picks the
    /// importer; unknown extensions fall back to content sniffing (FBX binary magic / ASCII
    /// header token / GLB 'glTF' magic / glTF JSON). Public so UI listings
    /// inspect files through the SAME import path the pipeline uses (no duplicate sniffing
    /// logic caller-side).
    /// </summary>
    /// <param name="data">Raw file bytes.</param>
    /// <param name="fileName">File name; only the extension is consulted.</param>
    /// <param name="sampleFps">Resample rate for the imported clips; null = importer default
    /// (30 fps).</param>
    /// <exception cref="FormatException">Thrown when the bytes are not a readable
    /// motion, FBX or glTF animation.</exception>
    public static SourceScene ImportSource(
        byte[] data, string fileName, float? sampleFps = null,
        Func<string, byte[]>? externalBufferResolver = null)
    {
        ArgumentNullException.ThrowIfNull(data);
        ArgumentNullException.ThrowIfNull(fileName);

        var fbxOptions = sampleFps is { } fbxFps ? new FbxImportOptions { SampleFps = fbxFps } : null;
        var gltfOptions = sampleFps is not null || externalBufferResolver is not null
            ? new GltfImportOptions
            {
                SampleFps = sampleFps ?? 30f,
                ExternalBufferResolver = externalBufferResolver,
            }
            : null;
        var ext = ExtensionOf(fileName);
        return ext switch
        {
            "hmotion" => Motion.MotionDocument.Parse(data).ToSourceScene(sampleFps),
            "fbx" => FbxImporter.Import(data, fbxOptions),
            // .vrm = glTF 2.0 GLB container + VRM extension (the importer reads the authored
            // humanoid bone map into SourceScene.AuthoredMapping); unknown-extension VRM
            // bytes also land here via the GLB magic sniff below.
            "glb" or "gltf" or "vrm" => GltfImporter.Import(data, gltfOptions),
            _ => SniffFormat(data) switch
            {
                "fbx" => FbxImporter.Import(data, fbxOptions),
                "gltf" => GltfImporter.Import(data, gltfOptions),
                _ => throw new FormatException(
                    $"Unrecognized source format for '{fileName}' (expected .hmotion, .fbx, .glb, .gltf or .vrm)."),
            },
        };
    }

    private static string? SniffFormat(byte[] data)
    {
        // Binary FBX magic: "Kaydara FBX Binary  \0".
        const string fbxMagic = "Kaydara FBX Binary";
        if (StartsWithAscii(data, fbxMagic))
            return "fbx";

        // GLB magic: 'glTF' (0x46546C67 little-endian).
        if (StartsWithAscii(data, "glTF"))
            return "gltf";

        var head = Encoding.UTF8.GetString(data, 0, Math.Min(data.Length, 4096));
        if (head.Contains("FBXHeaderExtension", StringComparison.Ordinal))
            return "fbx"; // ASCII FBX
        var trimmed = head.TrimStart();
        if (trimmed.StartsWith("{", StringComparison.Ordinal)
            && head.Contains("\"asset\"", StringComparison.Ordinal))
            return "gltf"; // plain-JSON glTF
        return null;
    }

    private static bool StartsWithAscii(byte[] data, string prefix)
    {
        if (data.Length < prefix.Length)
            return false;
        for (var i = 0; i < prefix.Length; i++)
        {
            if (data[i] != (byte)prefix[i])
                return false;
        }
        return true;
    }

    /// <summary>
    /// THE mapping cascade, shared by conversion, UI file listings, and custom-target
    /// detection: explicit override → authored mapping (from the file itself, e.g. a VRM's
    /// humanoid bone map — authoritative ground truth at confidence 1.0) → user preset (via
    /// <paramref name="userPresetLookup"/>, keyed by <see cref="Mapping.SkeletonSignature"/>)
    /// → shipped preset detection → best-effort auto-map. The report's
    /// <see cref="MappingReportInfo.NeedsUserDecision"/> is true only on the auto path below
    /// the preset detection threshold — conversion still proceeds with that map; callers
    /// decide whether to ask/reject.
    /// </summary>
    /// <param name="skeleton">Source (or candidate target) skeleton.</param>
    /// <param name="mappingOverride">Explicit mapping (manual table / already-resolved user
    /// preset); wins outright when non-null — a deliberate user decision beats even the
    /// file's own bone map.</param>
    /// <param name="userPresetLookup">Editor-side user-preset hook: receives the skeleton's
    /// signature, returns the stored mapping or null. The facade itself can do no file IO.</param>
    /// <param name="authoredMapping">A mapping authored INSIDE the source file
    /// (<see cref="SourceScene.AuthoredMapping"/>, <see cref="MappingSource.Authored"/>);
    /// consulted before user presets because the file itself is authoritative.</param>
    public static (MappingResult Map, MappingReportInfo Report) ResolveMapping(
        SkeletonModel skeleton, MappingResult? mappingOverride = null,
        Func<string, MappingResult?>? userPresetLookup = null,
        MappingResult? authoredMapping = null)
    {
        ArgumentNullException.ThrowIfNull(skeleton);

        if (mappingOverride is not null)
            return (mappingOverride, BuildReport(mappingOverride, needsUserDecision: false, skeleton));

        if (authoredMapping is not null)
            return (authoredMapping, BuildReport(authoredMapping, needsUserDecision: false, skeleton));

        if (userPresetLookup is not null
            && userPresetLookup(Mapping.SkeletonSignature.Compute(skeleton)) is { } userPreset)
            return (userPreset, BuildReport(userPreset, needsUserDecision: false, skeleton));

        if (ProfileDetector.Detect(skeleton) is { } detected)
        {
            AutoMapper.CompleteSingleJointThumbs(skeleton, detected.Result);
            AutoMapper.CompleteFingersByTopology(skeleton, detected.Result);
            AutoMapper.PruneNonArticulatedFingerStubs(skeleton, detected.Result);
            VetoImpossibleHead(skeleton, detected.Result);
            return (detected.Result, BuildReport(detected.Result, needsUserDecision: false, skeleton));
        }

        var auto = AutoMapper.Map(skeleton);
        VetoImpossibleHead(skeleton, auto);
        var needsUserDecision = auto.Confidence < ProfileDetector.DetectionThreshold;
        return (auto, BuildReport(auto, needsUserDecision, skeleton));
    }

    /// <summary>
    /// Drops a detected/auto-mapped Head whose bone cannot anatomically drive a skull: its
    /// rest sits clearly BELOW the neck (or the topmost mapped spine joint). Real case: an
    /// Auto-Rig Pro export parks <c>head.x</c> at chest height ~90cm under <c>neck.x</c>
    /// with the skin bind compensating — the mesh is correct at rest, but every skull
    /// rotation replayed onto that bone sweeps the head geometry on the lever arm ("the
    /// head is stretched and it stretched more when I played the animation"). With the
    /// role unmapped the neck — whose pivot IS at the skull base on such rigs — carries
    /// head motion, and the bone holds its rest like any other unmapped helper.
    /// Neutral-rest corpus rigs measure the neck→head segment −8°…33° from character up
    /// (dot ≥ 0.55 even on the posed Defenses bind at 40.7°); the veto fires only past
    /// 101° (dot &lt; −0.2), an impossible carriage on any working rig. Explicit,
    /// authored and user-preset mappings are authoritative and never second-guessed.
    /// </summary>
    private static void VetoImpossibleHead(SkeletonModel skeleton, MappingResult map)
    {
        if (!map.RoleToBone.TryGetValue(BoneRole.Head, out var head)
            || !map.RoleToBone.TryGetValue(BoneRole.Hips, out var hips))
            return;

        var reference = map.RoleToBone.TryGetValue(BoneRole.Neck, out var neck)
            ? neck
            : SpineTop(map);
        if (reference is not { } refBone || refBone == hips)
            return;

        var rest = skeleton.RestWorld;
        // Axis-free "up": the body chain ascends hips → spine → neck by construction, so
        // hips→reference is the rig's own vertical regardless of world axis convention.
        var up = rest[refBone].Pos - rest[hips].Pos;
        var seg = rest[head].Pos - rest[refBone].Pos;
        if (up.LengthSquared() < 1e-6f || seg.Length() < 0.05f * up.Length())
            return; // degenerate spine / head stacked on the neck: nothing to judge

        if (Vector3.Dot(Vector3.Normalize(seg), Vector3.Normalize(up)) >= -0.2f)
            return;

        map.RoleToBone.Remove(BoneRole.Head);
        // The neck of a broken skull region rests with the head. On the real case the
        // neck bone skins the skull AND a torso column (its weights are where the head's
        // should be), so any solved neck bend shears half the body: the source spreads
        // its idle hunch through its spine while this target's spine stays put, and the
        // faithful neck world replay turned into a ~19° LOCAL kink rendered as a hump
        // grafted onto the character's back. Skull attitude rides the spine instead.
        var neckNote = "";
        if (map.RoleToBone.Remove(BoneRole.Neck))
            neckNote = $" Its neck '{skeleton[neck].Name}' rests too (on such exports it "
                + "carries the skull/torso skin the head joint should).";
        map.Notes.Add(
            $"Head '{skeleton[head].Name}' unmapped: its rest sits below "
            + $"'{skeleton[refBone].Name}' - not a skull joint the solver can drive "
            + "(rotations would sweep the head geometry on the offset lever arm)."
            + neckNote + " The spine carries the upper body; map manually to override.");
    }

    private static int? SpineTop(MappingResult map)
    {
        foreach (var role in new[]
        {
            BoneRole.Spine4, BoneRole.Spine3, BoneRole.Spine2, BoneRole.Spine1, BoneRole.Spine0,
        })
        {
            if (map.RoleToBone.TryGetValue(role, out var bone))
                return bone;
        }
        return null;
    }

    private static MappingReportInfo BuildReport(
        MappingResult map, bool needsUserDecision, SkeletonModel skeleton)
    {
        var report = new MappingReportInfo
        {
            ProfileName = map.ProfileName,
            Source = map.Source,
            Confidence = map.Confidence,
            NeedsUserDecision = needsUserDecision,
            MappedRoleCount = map.RoleToBone.Count,
            SkeletonSignature = Mapping.SkeletonSignature.Compute(skeleton),
        };
        report.Notes.AddRange(map.Notes);
        if (needsUserDecision)
            report.Notes.Add(
                $"No preset profile matched and auto-map confidence {map.Confidence:0.00} is below "
                + $"{ProfileDetector.DetectionThreshold:0.00}; proceeding with the best-effort auto map.");
        return report;
    }

    // ================================================================ naming

    private static string RequestedClipName(RetargetRequest request, SourceScene scene, int take)
    {
        var multipleTakes = scene.Clips.Count > 1;
        if (!string.IsNullOrWhiteSpace(request.ClipNameOverride))
            return multipleTakes ? $"{request.ClipNameOverride}_{take + 1}" : request.ClipNameOverride!;

        var takeName = scene.Clips[take].Name;
        if (!string.IsNullOrWhiteSpace(takeName) && takeName != "motion"
            && !takeName.Equals("mixamo.com", StringComparison.OrdinalIgnoreCase)
            && !IsExporterPlaceholderTake(takeName))
            return takeName;

        // BVH files (clip always named "motion"), Mixamo takes (always named
        // "mixamo.com"), Unreal exports (every stack named "Unreal Take") and
        // unnamed takes use the file stem.
        var stem = FileStem(request.SourceFileName);
        return multipleTakes ? $"{stem}_{take + 1}" : stem;
    }

    /// <summary>
    /// True for take names that identify the EXPORTER rather than the animation. Unreal's
    /// FBX exporter stamps <c>Unreal Take</c> into every AnimStack it writes (numbered —
    /// <c>Unreal Take 001</c> — when a sequence exports several), so a folder of UE clips
    /// arrives with one identical take name on every file. Treated as authored, that name
    /// beats the file stem in <see cref="RequestedClipName"/> and the whole batch collapses
    /// onto one clip name, which <see cref="UniqueClipName"/> then has to pull apart into
    /// <c>Unreal_Take</c>, <c>Unreal_Take_2</c>, <c>Unreal_Take_3</c>… — every file's real
    /// name lost, and the resulting sequence names carry no meaning in the vmdl. Falling
    /// through to the file stem restores the same per-file naming BVH and Mixamo sources
    /// already get. Matched as a PREFIX, and against the underscored spelling too, so the
    /// numbered variants and any already-sanitized re-import are covered.
    /// </summary>
    private static bool IsExporterPlaceholderTake(string takeName)
    {
        var trimmed = takeName.Trim();
        return trimmed.StartsWith("unreal take", StringComparison.OrdinalIgnoreCase)
            || trimmed.StartsWith("unreal_take", StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>Collision auto-suffixing across the batch: <c>name</c>, <c>name_2</c>, …
    /// (case-insensitive — the names also become DMX file names).</summary>
    private static string UniqueClipName(string name, HashSet<string> usedNames, bool autoSuffix)
    {
        if (usedNames.Add(name) || !autoSuffix)
            return name;
        for (var i = 2; ; i++)
        {
            var candidate = $"{name}_{i}";
            if (usedNames.Add(candidate))
                return candidate;
        }
    }

    /// <summary>
    /// Clip names become ModelDoc AnimFile node names and Source 2 sequence names, which
    /// must stay within <c>[A-Za-z0-9_]</c> — a take name like <c>mixamo.com</c> otherwise
    /// fails the vmdl compile with "Node 'mixamo.com' resolve failure". Runs of invalid
    /// characters collapse to a single underscore; case is preserved. Public so UIs that
    /// dry-run name-based detection (e.g. the locomotion-set scan over raw take names) see
    /// the SAME spelling conversion will produce — a take named <c>Walk N</c> becomes the
    /// clip <c>Walk_N</c>.
    /// </summary>
    public static string SanitizeClipName(string name)
    {
        var builder = new StringBuilder(name.Length);
        var lastWasUnderscore = false;
        foreach (var c in name)
        {
            if (c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or (>= '0' and <= '9') or '_')
            {
                builder.Append(c);
                lastWasUnderscore = c == '_';
            }
            else if (!lastWasUnderscore)
            {
                builder.Append('_');
                lastWasUnderscore = true;
            }
        }
        var sanitized = builder.ToString().Trim('_');
        return sanitized.Length > 0 ? sanitized : "clip";
    }

    private static string FileStem(string fileName)
    {
        var start = Math.Max(fileName.LastIndexOf('/'), fileName.LastIndexOf('\\')) + 1;
        var dot = fileName.LastIndexOf('.');
        var end = dot > start ? dot : fileName.Length;
        var stem = fileName.Substring(start, end - start);
        return stem.Length > 0 ? stem : "clip";
    }

    private static string ExtensionOf(string fileName)
    {
        var dot = fileName.LastIndexOf('.');
        if (dot < 0 || dot == fileName.Length - 1)
            return "";
        var ext = fileName.Substring(dot + 1);
        return ext.IndexOfAny(new[] { '/', '\\' }) >= 0 ? "" : ext.ToLowerInvariant();
    }

    private static string SanitizeFileName(string name)
    {
        var builder = new StringBuilder(name.Length);
        foreach (var c in name)
        {
            builder.Append(
                c is (>= 'a' and <= 'z') or (>= '0' and <= '9') or '_' or '-' ? c
                : c is >= 'A' and <= 'Z' ? char.ToLowerInvariant(c)
                : '_');
        }
        var sanitized = builder.ToString().Trim('_');
        return sanitized.Length > 0 ? sanitized : "clip";
    }

    private static string JoinAssetPath(string folder, string file)
    {
        var f = folder.Replace('\\', '/').TrimEnd('/');
        return f.Length == 0 ? file : f + "/" + file;
    }

    // ================================================================ target context

    /// <summary>Everything derived once per batch from the target rig: character up axis,
    /// foot chains, hips/root indices, IK-bone presence.</summary>
    internal sealed class TargetContext
    {
        public TargetRig Rig { get; }

        /// <summary>Target character up direction (midShoulders − midHips on the rest pose,
        /// via <see cref="CharacterFrame"/>); null when the rig lacks the bones for it.</summary>
        public Vector3? Up { get; }

        /// <summary>Target character frame (for the arm-IK basis change); null when not computable.</summary>
        public CharacterFrame? Frame { get; }

        /// <summary>Left/right leg chains from the rig's UpperLeg/LowerLeg/Foot/Toe roles;
        /// null when either leg is incompletely mapped.</summary>
        public (FootChain Left, FootChain Right)? FootChains { get; }

        /// <summary>Why <see cref="Up"/> / <see cref="FootChains"/> are unavailable (report note text).</summary>
        public string UpOrChainProblem { get; } = "";

        /// <summary>Target bone carrying the Hips role.</summary>
        public int? HipsIndex { get; }

        /// <summary>Dedicated translating root: a parentless Animated bone that is an
        /// ancestor of (and distinct from) the hips. Null on the s&amp;box rig (pelvis is
        /// itself parentless; root_IK is IkBaked).</summary>
        public int? DedicatedRootIndex { get; }

        /// <summary>True when the hips bone's direct parent is the dedicated root.</summary>
        public bool HipsParentIsRoot { get; }

        public bool HasIkBakedBones { get; }

        /// <summary>ConstraintDriven bone indices (twist/helper) — excluded from DMX
        /// channels per design §3; null when the rig has none. Face bones
        /// (<see cref="SboxBoneClassifier.IsFaceBone"/>) are NOT in this set even though
        /// their class is ConstraintDriven: they keep rest-local channels, because no
        /// constraint re-drives them in a compiled sequence (channel-less face joints
        /// bake statically — eyes detach from the moving head in ModelDoc).</summary>
        public IReadOnlySet<int>? ConstraintDrivenBones { get; }

        public TargetContext(TargetRig rig)
        {
            Rig = rig;
            HipsIndex = rig.BoneForRole(BoneRole.Hips);
            DedicatedRootIndex = FindDedicatedRoot(rig, HipsIndex);
            HipsParentIsRoot = HipsIndex is { } hips && DedicatedRootIndex is { } root
                && rig.Skeleton[hips].ParentIndex == root;
            foreach (var _ in rig.BonesOfClass(BoneClass.IkBaked))
            {
                HasIkBakedBones = true;
                break;
            }

            var constraintDriven = new HashSet<int>(rig.BonesOfClass(BoneClass.ConstraintDriven));
            // Face bones (eye_/ear_/face_) are ConstraintDriven by class but, unlike the
            // twist/helper bones, nothing re-drives them when a compiled sequence plays:
            // the model's AnimConstraintList never references them and the engine's eye
            // look-at / blinking only runs in game. They must KEEP their rest-local DMX
            // channels (the shipped fbx2dmx clips carry them too) or ModelDoc bakes the
            // channel-less joints statically and the eyes detach from the moving head
            // (see SboxBoneClassifier.IsFaceBone).
            constraintDriven.RemoveWhere(i => SboxBoneClassifier.IsFaceBone(rig.Skeleton[i].Name));
            ConstraintDrivenBones = constraintDriven.Count > 0 ? constraintDriven : null;

            try
            {
                Frame = CharacterFrame.Compute(rig.Skeleton, rig.ToMappingResult(), rig.Skeleton.RestWorld);
                Up = Frame.Up;
            }
            catch (ArgumentException e)
            {
                UpOrChainProblem = $"target character frame not computable ({e.Message})";
                return;
            }

            var left = LegChain(rig, BoneRole.UpperLegL, BoneRole.LowerLegL, BoneRole.FootL, BoneRole.ToeL);
            var right = LegChain(rig, BoneRole.UpperLegR, BoneRole.LowerLegR, BoneRole.FootR, BoneRole.ToeR);
            if (left is not null && right is not null)
                FootChains = (left, right);
            else
                UpOrChainProblem = "target rig does not map a complete UpperLeg/LowerLeg/Foot chain on both sides";
        }

        private static FootChain? LegChain(TargetRig rig, BoneRole upper, BoneRole lower, BoneRole foot, BoneRole toe)
            => rig.BoneForRole(upper) is { } hip
               && rig.BoneForRole(lower) is { } knee
               && rig.BoneForRole(foot) is { } ankle
                ? new FootChain { Hip = hip, Knee = knee, Ankle = ankle, Toe = rig.BoneForRole(toe) }
                : null;

        private static int? FindDedicatedRoot(TargetRig rig, int? hipsIndex)
        {
            if (hipsIndex is not { } hips)
                return null;
            // Walk up from the hips; the topmost ancestor qualifies when it is a parentless
            // Animated bone distinct from the hips itself.
            var top = hips;
            while (rig.Skeleton[top].ParentIndex >= 0)
                top = rig.Skeleton[top].ParentIndex;
            return top != hips && rig.ClassOf(top) == BoneClass.Animated ? top : null;
        }
    }

    // ================================================================ arm effector IK

    /// <summary>
    /// Optional wrist-reach cleanup: per frame, the source hand offset from its shoulder is
    /// limb-length-normalized, re-expressed in the target's character basis, and used as a
    /// two-bone IK goal for the target arm (<see cref="EffectorIk.ApplyGoals"/>).
    /// </summary>
    private static class ArmIkCleanup
    {
        /// <summary>Runs both arms; returns a problem note (and does nothing) when the
        /// prerequisites are missing, null on success.</summary>
        public static string? Apply(
            List<XForm[]> frames, SourceScene scene, MappingResult map,
            TargetRig rig, TargetContext context, int take)
        {
            if (context.Frame is not { } targetFrame)
                return context.UpOrChainProblem;

            CharacterFrame sourceFrame;
            try
            {
                sourceFrame = CharacterFrame.Compute(scene.Skeleton, map, scene.Skeleton.RestWorld);
            }
            catch (ArgumentException e)
            {
                return $"source character frame not computable ({e.Message})";
            }

            // Change of basis source space → target space (this library's convention:
            // a * b applies b first).
            var sourceToTarget = MathQ.Normalize(
                BasisRotation(targetFrame) * Quaternion.Conjugate(BasisRotation(sourceFrame)));

            var appliedAny = false;
            appliedAny |= ApplyArm(frames, scene, map, rig, sourceToTarget, take,
                BoneRole.UpperArmL, BoneRole.LowerArmL, BoneRole.HandL);
            appliedAny |= ApplyArm(frames, scene, map, rig, sourceToTarget, take,
                BoneRole.UpperArmR, BoneRole.LowerArmR, BoneRole.HandR);
            return appliedAny ? null : "no complete UpperArm/LowerArm/Hand chain mapped on source and target";
        }

        private static bool ApplyArm(
            List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,
            Quaternion sourceToTarget, int take, BoneRole upperRole, BoneRole lowerRole, BoneRole handRole)
        {
            if (!map.RoleToBone.TryGetValue(upperRole, out var srcUpper)
                || !map.RoleToBone.TryGetValue(lowerRole, out var srcLower)
                || !map.RoleToBone.TryGetValue(handRole, out var srcHand))
                return false;
            if (rig.BoneForRole(upperRole) is not { } tgtUpper
                || rig.BoneForRole(lowerRole) is not { } tgtLower
                || rig.BoneForRole(handRole) is not { } tgtHand)
                return false;

            var src = scene.Skeleton;
            var tgt = rig.Skeleton;
            var srcLen = Vector3.Distance(src.RestWorld[srcUpper].Pos, src.RestWorld[srcLower].Pos)
                       + Vector3.Distance(src.RestWorld[srcLower].Pos, src.RestWorld[srcHand].Pos);
            var tgtLen = Vector3.Distance(tgt.RestWorld[tgtUpper].Pos, tgt.RestWorld[tgtLower].Pos)
                       + Vector3.Distance(tgt.RestWorld[tgtLower].Pos, tgt.RestWorld[tgtHand].Pos);
            if (srcLen < 1e-4f || tgtLen < 1e-4f)
                return false;
            var scale = tgtLen / srcLen;

            var sourceFrames = scene.Clips[take].Frames;
            var count = Math.Min(frames.Count, sourceFrames.Count);
            var goals = new Vector3[frames.Count];
            for (var f = 0; f < frames.Count; f++)
            {
                var srcWorld = new Pose(sourceFrames[Math.Min(f, count - 1)]).ToWorld(src);
                var tgtWorld = new Pose(frames[f]).ToWorld(tgt);
                var reach = srcWorld[srcHand].Pos - srcWorld[srcUpper].Pos;
                goals[f] = tgtWorld[tgtUpper].Pos + Vector3.Transform(reach, sourceToTarget) * scale;
            }

            EffectorIk.ApplyGoals(
                frames, tgt,
                new LimbChain { Upper = tgtUpper, Lower = tgtLower, End = tgtHand },
                goals, RestBendAxis(tgt, tgtUpper, tgtLower, tgtHand));
            return true;
        }

        /// <summary>Hinge-axis fallback from the rest bend plane (elbow), like the foot pass.</summary>
        internal static Vector3 RestBendAxis(SkeletonModel skeleton, int upper, int lower, int end)
        {
            var a = skeleton.RestWorld[upper].Pos;
            var b = skeleton.RestWorld[lower].Pos;
            var c = skeleton.RestWorld[end].Pos;
            var axis = Vector3.Cross(c - a, b - a);
            if (axis.LengthSquared() > 1e-6f)
                return Vector3.Normalize(axis);
            var limb = c - a;
            axis = Vector3.Cross(limb, Vector3.UnitY);
            if (axis.LengthSquared() < 1e-6f)
                axis = Vector3.Cross(limb, Vector3.UnitZ);
            return axis.LengthSquared() > 1e-12f ? Vector3.Normalize(axis) : Vector3.UnitX;
        }

        /// <summary>Rotation taking canonical character axes (X=lateral, Y=up, Z=forward)
        /// to the rig's world axes.</summary>
        private static Quaternion BasisRotation(CharacterFrame frame)
        {
            var m = new Matrix4x4(
                frame.Lateral.X, frame.Lateral.Y, frame.Lateral.Z, 0f,
                frame.Up.X, frame.Up.Y, frame.Up.Z, 0f,
                frame.Forward.X, frame.Forward.Y, frame.Forward.Z, 0f,
                0f, 0f, 0f, 1f);
            return MathQ.Normalize(Quaternion.CreateFromRotationMatrix(m));
        }
    }
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Skeleton/Skeleton.cs
Game library
#nullable enable annotations

using System;
using System.Collections.Generic;
using HumanoidMocapX.Core.Maths;

namespace HumanoidMocapX.Core.Skeleton;

/// <summary>
/// Immutable bone hierarchy with rest pose. Bones are stored topologically sorted
/// (every bone's parent precedes it), which lets forward kinematics run as a single
/// in-order pass. Supports multiple roots (e.g. the s&amp;box rig has both
/// <c>root_IK</c> and <c>pelvis</c> as parentless bones).
/// </summary>
public sealed class Skeleton
{
    private readonly Bone[] _bones;
    private readonly XForm[] _restWorld;
    private readonly Dictionary<string, int> _indexByName;

    private Skeleton(Bone[] bones, XForm[] restWorld, Dictionary<string, int> indexByName)
    {
        _bones = bones;
        _restWorld = restWorld;
        _indexByName = indexByName;
    }

    /// <summary>Number of bones.</summary>
    public int Count => _bones.Length;

    /// <summary>All bones, topologically sorted (parents before children).</summary>
    public IReadOnlyList<Bone> Bones => _bones;

    /// <summary>Rest (bind) world transforms, indexed like <see cref="Bones"/>.</summary>
    public IReadOnlyList<XForm> RestWorld => _restWorld;

    /// <summary>Bone name to index lookup.</summary>
    public IReadOnlyDictionary<string, int> IndexByName => _indexByName;

    /// <summary>The bone at <paramref name="index"/>.</summary>
    public Bone this[int index] => _bones[index];

    /// <summary>Returns the index of the named bone, or -1 when absent.</summary>
    public int IndexOf(string name) => _indexByName.TryGetValue(name, out var index) ? index : -1;

    /// <summary>
    /// Builds a skeleton from bone definitions in any order: validates names and parent links,
    /// topologically sorts (stable — input order is preserved among bones whose parents are
    /// already placed), and computes rest world transforms.
    /// </summary>
    /// <exception cref="ArgumentException">
    /// Thrown on duplicate bone names, unknown parent names, or parent cycles.
    /// </exception>
    public static Skeleton Create(IReadOnlyList<BoneDefinition> definitions)
    {
        ArgumentNullException.ThrowIfNull(definitions);

        var count = definitions.Count;
        var originalIndexByName = new Dictionary<string, int>(count, StringComparer.Ordinal);
        for (var i = 0; i < count; i++)
        {
            var name = definitions[i].Name;
            if (string.IsNullOrEmpty(name))
                throw new ArgumentException($"Bone at position {i} has an empty name.", nameof(definitions));
            if (!originalIndexByName.TryAdd(name, i))
                throw new ArgumentException($"Duplicate bone name '{name}'.", nameof(definitions));
        }

        foreach (var def in definitions)
        {
            if (def.ParentName is not null && !originalIndexByName.ContainsKey(def.ParentName))
                throw new ArgumentException(
                    $"Bone '{def.Name}' references unknown parent '{def.ParentName}'.", nameof(definitions));
            if (def.ParentName == def.Name)
                throw new ArgumentException($"Bone '{def.Name}' is its own parent.", nameof(definitions));
        }

        // Stable topological sort: repeatedly place, in input order, every bone whose parent
        // is already placed. O(n^2) worst case — fine for skeleton-sized inputs (~100 bones).
        var newIndexByOriginal = new int[count];
        Array.Fill(newIndexByOriginal, -1);
        var order = new List<int>(count);
        while (order.Count < count)
        {
            var progressed = false;
            for (var i = 0; i < count; i++)
            {
                if (newIndexByOriginal[i] >= 0)
                    continue;
                var parentName = definitions[i].ParentName;
                if (parentName is not null && newIndexByOriginal[originalIndexByName[parentName]] < 0)
                    continue;
                newIndexByOriginal[i] = order.Count;
                order.Add(i);
                progressed = true;
            }
            if (!progressed)
                throw new ArgumentException("Bone hierarchy contains a parent cycle.", nameof(definitions));
        }

        var bones = new Bone[count];
        var restWorld = new XForm[count];
        var indexByName = new Dictionary<string, int>(count, StringComparer.Ordinal);
        for (var newIndex = 0; newIndex < count; newIndex++)
        {
            var def = definitions[order[newIndex]];
            var parentIndex = def.ParentName is null ? -1 : newIndexByOriginal[originalIndexByName[def.ParentName]];
            bones[newIndex] = new Bone(newIndex, def.Name, parentIndex, def.RestLocal);
            restWorld[newIndex] = parentIndex < 0
                ? def.RestLocal
                : XForm.Compose(restWorld[parentIndex], def.RestLocal);
            indexByName.Add(def.Name, newIndex);
        }

        return new Skeleton(bones, restWorld, indexByName);
    }
}
notpointless.chomnr_humanoid_mocap_x / HumanoidMocap/Core/Target/KvBool.cs
Game library
#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace HumanoidMocapX.Core.Target;

/// <summary>A KV3 boolean.</summary>
public sealed class KvBool : KvValue
{
    /// <summary>The boolean value.</summary>
    public bool Value { get; }

    /// <summary>Creates a boolean value.</summary>
    public KvBool(bool value) => Value = value;
}
notpointless.chomnr_humanoid_mocap_x / dev/clip_checks.cs
Game library
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using HumanoidMocapX.Core;
using HumanoidMocapX.Core.Formats.Fbx;
using HumanoidMocapX.Core.Motion;
using HumanoidMocapX.Core.Target;
using HumanoidMocapX.EditorTools;
using HumanoidMocapX.Inference;
using Sandbox;
using static Sandbox.Internal.GlobalGameNamespace;

namespace HumanoidMocapX.Checks;

/// <summary>Runs the full model sequence on a 5–10-second predecoded video fixture.
/// This developer check excludes production decoding and visual motion acceptance.</summary>
public static class ClipChecks
{
    public sealed record Fixture(string RgbaPath, int Width, int Height, int Frames, string SourceVideo,
        string FlowPath, string SamPath, string MhrPath, string OmegaPath, string DetectorPath, string SmplPath, string RigDirectory,
        int CameraInterval = 10, FlowModel Model = FlowModel.Latest);

    /// <summary>Writes per-stage evidence, motion documents and Human/Citizen FBX
    /// exports. Requires installed released weights and a fresh writable result directory.</summary>
    public static async Task<object> Run(string fixturePath, string directory, CancellationToken cancellation)
    {
        var fixture = JsonSerializer.Deserialize<Fixture>(await File.ReadAllTextAsync(fixturePath, cancellation))
            ?? throw new ArgumentException("Missing clip fixture.");
        if (fixture.Frames is < 150 or > 300) throw new ArgumentException("Clip validation requires 5–10 seconds at 30 fps.");
        if (Directory.Exists(directory)) throw new ArgumentException("Use a fresh validation directory to avoid overwriting evidence.");
        Directory.CreateDirectory(directory);
        await File.WriteAllTextAsync(Path.Combine(directory, "fixture.json"), JsonSerializer.Serialize(fixture), cancellation);
        var processor = Processor(fixture); using var frames = new RawFrames(fixture);
        await Task.Run(() => FlowCheckpoint.LoadDecoder(fixture.FlowPath, fixture.SmplPath, cancellation), cancellation);
        var timer = Stopwatch.StartNew(); var times = new Dictionary<string, double>();
        var person = await processor.DetectAsync(frames, cancellation); times["Detection"] = timer.Elapsed.TotalSeconds;
        if (person.First != 0 || person.Count != frames.Count) throw new InvalidDataException("The validation fixture must show the person in every frame.");
        var boxes = person.Boxes; await Save("boxes.json", boxes); await Save("timings.json", times); timer.Restart();
        var camera = await processor.CameraAsync(frames, cancellation); times["Camera"] = timer.Elapsed.TotalSeconds;
        await Save("rotations.json", camera.Rotations); await Save("intrinsics.json", camera.Intrinsics); await Save("travel.json", camera.Travel); await Save("timings.json", times); timer.Restart();
        var (features, observations) = await processor.FeaturesAsync(frames, boxes, camera.Intrinsics, cancellation); times["Features"] = timer.Elapsed.TotalSeconds;
        await Save("features.json", features); await Save("observations.json", observations); await Save("timings.json", times); timer.Restart();
        var motion = await processor.GenerateAsync(features, camera.Rotations, frames.Count, cancellation); times["Generation"] = timer.Elapsed.TotalSeconds;
        var exports = await Export(fixture, motion, new ObservedDetail(observations, camera.Rotations, camera.Travel), directory, cancellation); await Save("timings.json", times);
        var result = new { Passed = true, PredecodedFixture = true, Frames = frames.Count, Seconds = frames.Count / 30.0, StageSeconds = times, Exports = exports };
        await Save("result.json", result);
        return result;

        Task Save<T>(string name, T value) => File.WriteAllTextAsync(Path.Combine(directory, name), JsonSerializer.Serialize(value), cancellation);
    }

    /// <summary>Repeats generation/export from this check's saved features. For
    /// developer diagnosis only: the caller must preserve the same fixture and weights.</summary>
    public static async Task<object> Generate(string directory, CancellationToken cancellation)
    {
        var fixture = JsonSerializer.Deserialize<Fixture>(await File.ReadAllTextAsync(Path.Combine(directory, "fixture.json"), cancellation));
        var features = JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(Path.Combine(directory, "features.json"), cancellation));
        var rotations = JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(Path.Combine(directory, "rotations.json"), cancellation));
        var motion = await Processor(fixture).GenerateAsync(features, rotations, fixture.Frames, cancellation);
        var observed = Path.Combine(directory, "observations.json");
        var traveled = Path.Combine(directory, "travel.json");
        var travel = File.Exists(traveled) ? JsonSerializer.Deserialize<float>(await File.ReadAllTextAsync(traveled, cancellation)) : float.NaN;
        var detail = File.Exists(observed) ? new ObservedDetail(JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(observed, cancellation)), rotations, travel) : null;
        return await Export(fixture, motion, detail, directory, cancellation);
    }

    static FlowVideoProcessor Processor(Fixture fixture) => new(new(fixture.FlowPath, fixture.SamPath, fixture.MhrPath, fixture.OmegaPath, fixture.DetectorPath, fixture.SmplPath),
        new() { CameraInterval = fixture.CameraInterval, Model = fixture.Model }, message => Log.Info(message));

    static Task<object> Export(Fixture fixture, FlowMotion motion, ObservedDetail detail, string directory, CancellationToken cancellation) => Task.Run<object>(async () =>
    {
        motion.Video = fixture.SourceVideo; motion.Name = Path.GetFileNameWithoutExtension(fixture.SourceVideo); var document = motion.ToDocument(); detail?.Apply(document);
        var bytes = Encoding.UTF8.GetBytes(document.ToJson()); await File.WriteAllBytesAsync(Path.Combine(directory, "capture.hmotion"), bytes, cancellation);
        await File.WriteAllTextAsync(Path.Combine(directory, "flow-motion.json"), JsonSerializer.Serialize(motion), cancellation);
        var results = new List<object>();
        foreach (var citizen in new[] { false, true })
        {
            cancellation.ThrowIfCancellationRequested(); var name = citizen ? "citizen" : "human";
            var rig = await File.ReadAllTextAsync(Path.Combine(fixture.RigDirectory, citizen ? "target_rig_sbox_citizen.json" : "target_rig_sbox.json"), cancellation);
            var target = citizen ? RetargetTargetSpec.SboxCitizen(rig) : RetargetTargetSpec.SboxDefault(rig);
            var result = Retargeter.Convert(new RetargetRequest
            {
                SourceData = bytes,
                SourceFileName = "capture.hmotion",
                FootPlantCleanup = true,
                MocapCorrections = new TargetCorrectionSettings { FirstPerson = false, StabilizeFeet = true }
            }, target);
            if (!result.Success) throw new Exception("Clip retarget failed: " + string.Join("; ", result.Errors.Concat(result.Clips.Select(c => c.Error))));
            var clip = result.Clips.Single();
            foreach (var poses in clip.SolvedFrames) foreach (var pose in poses)
                if (!float.IsFinite(pose.Pos.Length()) || !float.IsFinite(pose.Rot.Length())) throw new Exception("Non-finite target animation.");
            var times = Enumerable.Range(0, clip.SolvedFrames.Count).Select(i => i / (double)clip.Fps).ToArray();
            var exported = ModelDocFbxExport.Write(target.Rig.Skeleton, motion.Name, clip.SolvedFrames, times, clip.Fps, target.UpAxis, "WorldRelative");
            var roundTrip = FbxImporter.Import(exported);
            if (roundTrip.Clips.Count != 1 || roundTrip.Clips[0].Frames.Count != clip.SolvedFrames.Count)
                throw new Exception("Target FBX lost animation frames.");
            var path = Path.Combine(directory, name + ".fbx"); await File.WriteAllBytesAsync(path, exported, cancellation);
            results.Add(new { Target = name, Frames = clip.SolvedFrames.Count, Bones = target.Rig.Skeleton.Count, FbxBytes = exported.Length, Path = path });
        }
        return results;
    }, cancellation);

    sealed class RawFrames : ICaptureFrames, IDisposable
    {
        readonly FileStream stream;
        readonly int bytes;
        public int Width { get; }
        public int Height { get; }
        public int Count { get; }

        internal RawFrames(Fixture fixture)
        {
            Width = fixture.Width; Height = fixture.Height; Count = fixture.Frames;
            if (Width < 1 || Height < 1 || (long)Width * Height > 33_177_600) throw new ArgumentException("Invalid RGBA fixture dimensions.");
            bytes = checked(Width * Height * 4);
            stream = new(fixture.RgbaPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 1024, FileOptions.Asynchronous | FileOptions.RandomAccess);
            if (stream.Length != (long)bytes * Count) { stream.Dispose(); throw new ArgumentException("RGBA fixture length does not match its declared frame count."); }
        }

        public async ValueTask ReadAsync(int frame, Memory<byte> rgba, CancellationToken cancellation)
        {
            if ((uint)frame >= (uint)Count || rgba.Length != bytes) throw new ArgumentException("Invalid fixture frame or destination size.");
            cancellation.ThrowIfCancellationRequested(); stream.Position = (long)frame * bytes;
            await stream.ReadExactlyAsync(rgba, cancellation);
        }

        public void Dispose() => stream.Dispose();
    }
}
notpointless.chomnr_humanoid_mocap_x / dev/sam_frame_checks.cs
Game library
using System.Diagnostics;
using System.Text.Json;
using HumanoidMocapX.EditorTools;
using HumanoidMocapX.Inference;
using Sandbox;

namespace HumanoidMocapX.Checks;

/// <summary>Runs released YOLOX, SAM DINOv3, body decoder and MHR on a real frame.
/// This is an isolated body-pass diagnostic, not full video or hand refinement.</summary>
public static class SamFrameChecks
{
    /// <summary>Writes crop, keypoint and feature evidence to a JSON file. Requires
    /// a visible person in an RGBA8 frame and installed, verified model files.</summary>
    public static async Task<object> Run(string samPath, string mhrPath, string detectorPath, string rgbaPath,
        int width, int height, string resultPath, CancellationToken cancellation)
    {
        var pixels = await File.ReadAllBytesAsync(rgbaPath, cancellation);
        var box = await Detect(pixels, width, height, detectorPath, cancellation);
        var shape = DinoShape.Sam(); var crop = new SamCrop(box.Left, box.Top, box.Right, box.Bottom, shape);
        var focal = (float)Math.Sqrt((double)width * width + (double)height * height);
        var intrinsics = new float[] { focal, 0, width / 2f, 0, focal, height / 2f, 0, 0, 1 }; var affine = new float[6]; crop.CopyAffine(affine);
        var rgb = new float[shape.ImageElements]; var rayEncoder = new SamRays(shape); var rays = new float[rayEncoder.Elements];
        await Task.Run(() => { crop.Prepare(pixels, width, height, rgb, cancellation); rayEncoder.Prepare(intrinsics, affine, rays, cancellation); }, cancellation);
        var context = new float[shape.Patches * shape.Channels]; var positions = new float[context.Length];
        var imageTimes = await Encode(samPath, shape, rgb, rays, context, positions, cancellation);
        var model = await Task.Run(() => MhrCheckpoint.LoadBody(mhrPath, cancellation), cancellation);
        var pose = await Task.Run(() => SamCheckpoint.LoadPoseHead(samPath, model, false, cancellation), cancellation);
        var decoderShape = new SamDecoderShape(SamInitialTokens.Count, shape.Patches);
        var camera = await Task.Run(() => new SamPredictionHead(VisionCheckpoint.LoadSamHead(samPath, false, cancellation), false, true), cancellation);
        var keypoints = await Task.Run(() => new SamKeypointFeedback(VisionCheckpoint.LoadSamFeedback(samPath, false, cancellation), decoderShape, 32, 32), cancellation);
        var projection = new SamProjection(intrinsics, affine, crop.CenterX, crop.CenterY, crop.Size, shape);
        var feedback = new SamDecoderFeedback(decoderShape, pose, camera, keypoints); feedback.Prepare(projection, context);
        var tokens = new float[decoderShape.TokenElements]; var tokenPositions = new float[tokens.Length]; var decoded = new float[tokens.Length];
        await Task.Run(() => new SamInitialTokens(VisionCheckpoint.LoadSamInitialTokens(samPath, false, cancellation))
            .Run(projection, tokens, tokenPositions, cancellation), cancellation);
        var decoderWeights = await Task.Run(() => VisionCheckpoint.LoadSamDecoder(samPath, false, cancellation), cancellation);
        await GameTask.MainThread(); var decoder = new SamGpuDecoder(decoderWeights, decoderShape); var timer = Stopwatch.StartNew();
        try
        {
            await decoder.RunAsync(tokens, context, tokenPositions, positions, decoded, feedback.Update, cancellation);
            await Task.Run(() => feedback.Finish(decoded, cancellation), cancellation);
        }
        finally { await GameTask.MainThread(); decoder.Dispose(); }
        var decodeMilliseconds = timer.Elapsed.TotalMilliseconds;
        var cropped = new float[140]; var depths = new float[70]; var translation = new float[3]; var imagePoints = new float[140];
        projection.Run(pose.Keypoints, feedback.CameraParameters, cropped, depths, translation);
        for (var i = 0; i < 70; i++)
        {
            imagePoints[i * 2] = ((cropped[i * 2] + .5f) * shape.Width - affine[2]) / affine[0];
            imagePoints[i * 2 + 1] = ((cropped[i * 2 + 1] + .5f) * shape.Height - affine[5]) / affine[4];
        }
        var result = new
        {
            BodyPassOnly = true,
            Width = width,
            Height = height,
            Box = box,
            Crop = new { crop.CenterX, crop.CenterY, crop.Size },
            ImageMilliseconds = imageTimes,
            DecodeMilliseconds = decodeMilliseconds,
            ImageKeypoints = imagePoints,
            KeypointsMetres = pose.Keypoints.ToArray(),
            Depths = depths,
            Translation = translation,
            BodyFeature = decoded.AsSpan(0, decoderShape.Width).ToArray(),
            ModelParameters = pose.Model.ToArray()
        };
        await File.WriteAllTextAsync(resultPath, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }), cancellation);
        return new
        {
            Passed = true,
            BodyPassOnly = true,
            Box = box,
            Keypoints = 70,
            BodyFeatureChannels = decoderShape.Width,
            ImageMilliseconds = imageTimes,
            DecodeMilliseconds = decodeMilliseconds,
            ResultPath = resultPath
        };
    }

    static async Task<YoloBox> Detect(byte[] pixels, int width, int height, string path, CancellationToken cancellation)
    {
        var network = new YoloNetwork(); var weights = await Task.Run(() => YoloCheckpoint.Load(path, network, cancellation), cancellation);
        await GameTask.MainThread(); var detector = new YoloGpuDetector(network, weights);
        try
        {
            var boxes = new YoloBox[YoloNetwork.Predictions]; var count = await detector.DetectAsync(pixels, width, height, boxes, cancellation);
            if (count < 1) throw new Exception("SAM frame fixture contains no detected person.");
            return boxes[0];
        }
        finally { await GameTask.MainThread(); detector.Dispose(); }
    }

    static async Task<double[]> Encode(string path, DinoShape shape, float[] rgb, float[] rays, float[] context, float[] positions, CancellationToken cancellation)
    {
        var backbone = await Task.Run(() => VisionCheckpoint.LoadSamBackbone(path, cancellation), cancellation);
        var body = await Task.Run(() => VisionCheckpoint.LoadSamImageConditioning(path, false, cancellation), cancellation);
        var hand = await Task.Run(() => VisionCheckpoint.LoadSamImageConditioning(path, true, cancellation), cancellation);
        await GameTask.MainThread(); var encoder = new SamGpuImageEncoder(backbone, body, hand, shape);
        try
        {
            var timer = Stopwatch.StartNew(); await encoder.RunAsync(rgb, rays, context, false, cancellation);
            var first = timer.Elapsed.TotalMilliseconds; var previous = context.ToArray();
            await GameTask.MainThread(); timer.Restart(); await encoder.RunAsync(rgb, rays, context, false, cancellation);
            var repeated = timer.Elapsed.TotalMilliseconds;
            if (!previous.SequenceEqual(context)) throw new Exception("SAM image encoding did not repeat exactly.");
            encoder.CopyPositions(positions); return new[] { first, repeated };
        }
        finally { await GameTask.MainThread(); encoder.Dispose(); }
    }
}
notpointless.chomnr_humanoid_mocap_x / Editor/AccountBar.cs
Editor library
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Editor;
using Sandbox;

namespace HumanoidMocapX.EditorTools;

/// <summary>The strip across the top of the X window. With a provider: avatar, name, status pills,
/// account ID and limits, then icon buttons for the queue, adding videos and sign-out. On a processing
/// machine: its SSH address. On this computer: the GPU. Before setup: a pointer to settings. Missing
/// names and pictures show as not provided; account details and setup live in Mocap adjustments › Processing.</summary>
sealed class AccountBar : Widget
{
    readonly HostingSettings settings;
    readonly QueueTracker queue;
    readonly AccountAvatar avatar;
    readonly Label name, details, problem;
    readonly Layout pills;
    readonly Button signIn;
    readonly BadgeButton queueButton;
    readonly IconButton add, signOut;
    CancellationTokenSource pending;

    /// <summary>Provider mode when <paramref name="queue"/> is set, otherwise the processing machine
    /// or this computer, or a pointer to settings while processing is not <paramref name="configured"/>.</summary>
    internal AccountBar(Widget parent, HostingSettings settings, SshSettings machine, QueueTracker queue, bool configured, Action openSetup) : base(parent)
    {
        this.settings = settings; this.queue = queue;
        Layout = Layout.Row(); Layout.Margin = new Sandbox.UI.Margin(12, 10, 12, 10); Layout.Spacing = 10;
        avatar = Layout.Add(new AccountAvatar(this, 34));
        var text = Layout.AddColumn(1); text.Spacing = 2;
        var top = text.AddRow(); top.Spacing = 8;
        name = top.Add(Ui.Bold(new Label("", this), 14));
        pills = top.AddRow(); pills.Spacing = 6;
        top.AddStretchCell();
        details = text.Add(Ui.Muted(new Label("", this), small: true));
        problem = Layout.Add(Ui.Error(this));
        if (!configured)
        {
            avatar.ShowIcon("settings");
            name.Text = "Not set up";
            details.Text = "Choose where videos are processed: settings (top right) › Processing › Setup.";
            return;
        }
        if (queue is null && machine.Enabled)
        {
            avatar.ShowIcon("dns");
            name.Text = "Processing machine";
            details.Text = $"{machine.Address} over SSH · videos are copied there for processing";
            return;
        }
        if (queue is null)
        {
            avatar.ShowIcon("memory");
            name.Text = "This computer";
            var gpu = Sandbox.Engine.SystemInfo.Gpu is { Length: > 0 } gpuName && gpuName != "unset" ? gpuName : "This GPU";
            details.Text = $"{gpu} · up to {FlowVideoProcessor.LaneCapacity()} frames at once · videos never leave this computer";
                return;
        }
        signIn = Layout.Add(Ui.Primary("Sign in", "login", () => _ = SignInAsync(openSetup)));
        queueButton = Layout.Add(new BadgeButton(this, "format_list_bulleted", OpenQueue, "Queue: your jobs on the provider"));
        add = Layout.Add(Ui.Icon(this, "playlist_add", () => QueuePopup.AddVideos(queue), "Add videos to the queue"));
        signOut = Layout.Add(Ui.Icon(this, "logout", () => _ = SignOutAsync(), "Sign out"));
        settings.Changed += Refresh; queue.Changed += Refresh;
        Refresh();
    }

    void OpenQueue()
    {
        var popup = new QueuePopup(this, queue);
        popup.OpenAt(queueButton.ScreenRect.BottomLeft + new Vector2(queueButton.Width - popup.FixedWidth, 6));
    }

    void Refresh()
    {
        if (!this.IsValid()) return;
        var profile = settings.SignedIn ? settings.Profile : null;
        var label = EditorCookie.Get(ProcessingSetup.ProviderLabelCookie, "");
        signIn.Visible = profile is null; signIn.Text = label.Length > 0 ? "Sign in with " + label : "Sign in";
        queueButton.Visible = add.Visible = signOut.Visible = profile is not null;
        queueButton.Count = queue.Active;
        pills.Clear(true);
        if (profile is null)
        {
            name.Text = "Signed out"; details.Text = Host(); avatar.ShowIcon("person");
            return;
        }
        var user = profile.User;
        name.Text = Clip(user.Name ?? user.Username, 32) ?? "Name not provided";
        var (status, color) = profile switch
        {
            { Admin: true } => ("Admin", Ui.Accent),
            { CanProcess: true } => ("Whitelisted", Ui.Accent),
            { InGuild: false } => ("Join the Discord server", Theme.Yellow),
            _ => ("Not whitelisted", Theme.Red)
        };
        pills.Add(new Pill(this, status, color));
        if (profile.Limits is { Priority: true }) pills.Add(new Pill(this, "Priority", Theme.Yellow));
        details.Text = $"{Clip(user.Id, 40)} · {Host()}" + (profile.Limits is { } limit ? " · " + Describe(limit) : "");
        details.ToolTip = user.Id + ": your account ID on this provider. Give it to the provider to be whitelisted. Click to copy.";
        avatar.ShowAccount(user.Avatar, user.Name ?? user.Username);
    }

    protected override void OnMouseClick(MouseEvent e)
    {
        base.OnMouseClick(e);
        // The account ID line copies the ID, so users can send it to the provider.
        if (e.LeftMouseButton && details.IsUnderMouse && settings.Profile?.User.Id is { } id) EditorUtility.Clipboard.Copy(id);
    }

    static string Describe(HostLimits limit)
        => (limit.MaximumClipSeconds is { } clip ? $"clips up to {HostedCapture.Duration((int)clip)}" : "clips up to the provider's limit")
            + $" · uploads up to {limit.MaximumUploadBytes / (1024 * 1024)} MiB";

    string Host()
    {
        try { return settings.Endpoint().Host; } catch (ArgumentException) { return "No provider address"; }
    }

    static string Clip(string text, int length) => text is { } value && value.Length > length ? value[..(length - 1)] + "…" : text;

    async Task SignInAsync(Action openSetup)
    {
        if (pending is not null) return;
        if (ProcessingSetup.SavedProvider() is not { } provider) { openSetup(); return; }
        using var cancellation = new CancellationTokenSource(); pending = cancellation; var token = cancellation.Token;
        Ui.Show(problem, null); signIn.Enabled = false; signIn.Text = "Finish in your browser…";
        try { await ProcessingSetup.SignInAsync(settings, provider, token); }
        catch (Exception failure) when (ProcessingSetup.IsSignInFailure(failure))
        {
            await EditorPipeline.SwitchToMainThread();
            if (!token.IsCancellationRequested) Ui.Show(problem, failure is OperationCanceledException ? "Sign-in timed out. Try again." : failure.Message);
        }
        finally
        {
            await EditorPipeline.SwitchToMainThread();
            pending = null;
            if (signIn.IsValid()) { signIn.Enabled = true; Refresh(); }
        }
    }

    async Task SignOutAsync()
    {
        using var client = new HostSignIn();
        await client.SignOutAsync(settings);
    }

    public override void OnDestroyed()
    {
        settings.Changed -= Refresh; pending?.Cancel();
        if (queue is not null) queue.Changed -= Refresh;
        base.OnDestroyed();
    }

    protected override void OnPaint()
    {
        Paint.SetPen(Ui.CardEdge, 1);
        Paint.DrawLine(new Vector2(0, Height - .5f), new Vector2(Width, Height - .5f));
    }
}
notpointless.chomnr_humanoid_mocap_x / tests/test_sam_backbone.cs
UnitTest library
using HumanoidMocapX.EditorTools;
using HumanoidMocapX.Inference;

static class SamBackboneTests
{
    internal static void Run()
    {
        Dimensions(); Encoder(); Checkpoint();
        Console.WriteLine("PASS: 32-layer SAM DINOv3 encoder, SwiGLU gates, per-axis positions, selective checkpoint loading and allocation-free reuse");
    }

    static void Dimensions()
    {
        var shape = DinoShape.Sam();
        MotionTests.Equal(512, shape.Width); MotionTests.Equal(512, shape.Height);
        MotionTests.Equal(1280, shape.Channels); MotionTests.Equal(20, shape.Heads); MotionTests.Equal(32, shape.Depth);
        MotionTests.Equal(1024, shape.Patches); MotionTests.Equal(1029, shape.Tokens);
        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(511, 512));
        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(channels: 1281));
        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(heads: 3));
        var positions = OmegaPosition.Factors(2, 3, 5, new float[] { 1 }, true);
        // Row zero's Y coordinate is -1/2; column zero's X coordinate is -2/3.
        MotionTests.Near(-1, positions[5 * 4], 1e-6);
        MotionTests.Near(Math.Cos(-4 * Math.PI / 3), positions[5 * 4 + 2], 1e-6);
    }

    static void Encoder()
    {
        var shape = DinoShape.Sam(32, 48, 8, 2); var tensors = OmegaFixture.Sam(shape.Channels, shape.Heads);
        var encoder = new DinoImageEncoder(new(tensors), shape); var output = new float[shape.Patches * shape.Channels];
        var image = OmegaVisionTests.Image(shape.ImageElements, 0);
        for (var pass = 0; pass < 2; pass++)
        {
            if (pass > 0) Array.Reverse(image);
            encoder.Run(image, output);
            var expected = OmegaVisionReference.Image(tensors, image, shape.Height, shape.Width, shape.Channels, shape.Heads, true);
            for (var i = 0; i < output.Length; i++) MotionTests.Near(expected[i], output[i], 2e-4);
        }
        for (var warm = 0; warm < 3; warm++) encoder.Run(image, output);
        var before = GC.GetAllocatedBytesForCurrentThread(); encoder.Run(image, output);
        MotionTests.Equal(0L, GC.GetAllocatedBytesForCurrentThread() - before);
        using var cancelled = new CancellationTokenSource(); cancelled.Cancel();
        MotionTests.Throws<OperationCanceledException>(() => encoder.Run(image, output, cancelled.Token));
        MotionTests.Throws<ArgumentException>(() => encoder.Run(image, image.AsSpan(0, output.Length)));
        image[0] = 1.1f; MotionTests.Throws<ArgumentException>(() => encoder.Run(image, output));
        image[0] = float.NaN; MotionTests.Throws<ArgumentException>(() => encoder.Run(image, output));
        var block = new OmegaBlock(new(tensors), "backbone.encoder.blocks.0", 8, 2, false, true);
        var values = new float[shape.Tokens * shape.Channels];
        MotionTests.Throws<ArgumentException>(() => block.Run(values, new(shape.Tokens, 8), new(shape.Tokens, 8, 2, false), default));
    }

    static void Checkpoint()
    {
        var path = Path.Combine(Path.GetTempPath(), "sam-backbone-" + Guid.NewGuid().ToString("N") + ".pt");
        try
        {
            var tensors = OmegaFixture.Sam(8, 2);
            tensors.Add("decoder.unused", new("decoder.unused", new[] { float.NaN }, new[] { 1, 1, 1, 1, 1 }));
            foreach (var component in new string[] { null, "state_dict" })
            {
                CheckpointFixture.Write(path, tensors, component, ""); var loaded = VisionCheckpoint.LoadSamBackbone(path);
                foreach (var pair in tensors.Where(pair => pair.Key.StartsWith("backbone.encoder.")))
                    MotionTests.Check(loaded.Get(pair.Key, pair.Value.Shape).Data.AsSpan().SequenceEqual(pair.Value.Data), "SAM backbone checkpoint changed tensor layout");
                _ = new DinoImageEncoder(loaded, DinoShape.Sam(16, 32, 8, 2));
                using var cancelled = new CancellationTokenSource(); cancelled.Cancel();
                MotionTests.Throws<OperationCanceledException>(() => VisionCheckpoint.LoadSamBackbone(path, cancelled.Token));
                File.Delete(path);
            }
            tensors["backbone.encoder.blocks.31.mlp.w3.bias"].Data[0] = float.NaN;
            CheckpointFixture.Write(path, tensors, "state_dict", "");
            MotionTests.Throws<InvalidDataException>(() => VisionCheckpoint.LoadSamBackbone(path));
        }
        finally { File.Delete(path); }
    }
}
notpointless.chomnr_humanoid_mocap_x / tests/test_capture_inputs.cs
UnitTest library
using HumanoidMocapX.Inference;

static class CaptureInputTests
{
    internal static void Run()
    {
        var person = new YoloBox(10, 20, 110, 220, .8f); var other = new YoloBox(250, 10, 290, 100, .95f);
        var track = new PersonTrack(5); track.Add([other, person]); track.Add([person with { Left = 12, Right = 112 }, other]);
        track.Add([]); track.Add([person with { Left = 16, Right = 116 }]); track.Add([person with { Left = 18, Right = 118 }]);
        var span = track.Complete(); var boxes = span.Boxes;
        MotionTests.Equal(0, span.First); MotionTests.Equal(5, span.Count); MotionTests.Check(span.Note(2, 5) is null, "A fully visible person needs no note");
        for (var i = 0; i < 5; i++) { MotionTests.Equal(10f + i * 2, boxes[i * 4]); MotionTests.Equal(110f + i * 2, boxes[i * 4 + 2]); }
        MotionTests.Throws<InvalidOperationException>(() => track.Add([person]));
        var nobody = new PersonTrack(2); nobody.Add([]); nobody.Add([]); MotionTests.Throws<InvalidOperationException>(() => nobody.Complete());
        var unfinished = new PersonTrack(2); unfinished.Add([person]); MotionTests.Throws<InvalidOperationException>(() => unfinished.Complete());
        // The capture starts where the person first appears and ends at their last detection.
        var late = new PersonTrack(6); late.Add([]); late.Add([]); late.Add([person]); late.Add([]); late.Add([person with { Left = 14, Right = 114 }]); late.Add([]);
        var visible = late.Complete();
        MotionTests.Equal(2, visible.First); MotionTests.Equal(3, visible.Count); MotionTests.Equal(12, visible.Boxes.Length);
        MotionTests.Equal(12f, visible.Boxes[4]); MotionTests.Equal(14f, visible.Boxes[8]); MotionTests.Near(2 / 30d, visible.StartSeconds);
        MotionTests.Equal("The person is in view from 1.07 s to 1.17 s of the video, so only that part was captured.", visible.Note(1, 6));
        var uncertain = new PersonTrack(2); uncertain.Add([person]);
        MotionTests.Throws<InvalidOperationException>(() => uncertain.Add([person, person with { Left = 11, Right = 111 }]));
        // A person lost for more than half a second ends the capture; a later return is not joined on.
        var lost = new PersonTrack(18); lost.Add([person]); for (var i = 0; i < 15; i++) lost.Add([]);
        lost.Add([other]); lost.Add([person]);
        var kept = lost.Complete(); MotionTests.Equal(0, kept.First); MotionTests.Equal(1, kept.Count);
        MotionTests.Throws<ArgumentException>(() => new PersonTrack(1).Add([person with { Left = float.NaN }]));
        var reuse = new PersonTrack(20); var input = new[] { person }; for (var i = 0; i < 4; i++) reuse.Add(input);
        var before = GC.GetAllocatedBytesForCurrentThread(); reuse.Add(input); MotionTests.Equal(0L, GC.GetAllocatedBytesForCurrentThread() - before);
        var noise = new float[491 * 501]; var repeated = new float[noise.Length]; FlowNoise.Fill(noise, 0); FlowNoise.Fill(repeated, 0);
        MotionTests.Check(noise.SequenceEqual(repeated), "Initial noise must repeat for the same seed");
        var mean = noise.Average(v => (double)v); var variance = noise.Average(v => (double)v * v) - mean * mean;
        MotionTests.Near(0, mean, .01); MotionTests.Near(1, variance, .02);
        MotionTests.Check(noise.Min() < -3 && noise.Max() > 3 && noise.All(float.IsFinite), "Normal noise must cover both tails and remain finite");
        FlowNoise.Fill(repeated, 1); MotionTests.Check(!noise.SequenceEqual(repeated), "Different seeds must vary initial noise");
        using var stop = new CancellationTokenSource(); stop.Cancel();
        MotionTests.Throws<OperationCanceledException>(() => FlowNoise.Fill(noise, 0, stop.Token));
        MotionTests.Throws<ArgumentException>(() => FlowNoise.Fill(new float[490], 0));
        Console.WriteLine("PASS: person identity continuity, short-gap interpolation, ambiguous/lost-person rejection, allocation-free tracking and seeded standard-normal latents");
    }
}
notpointless.chomnr_humanoid_mocap_x / tests/test_ccd_ik.cs
UnitTest library
using System.Numerics;
using HumanoidMocapX.Core.Cleanup;
using HumanoidMocapX.Core.Maths;
using HumanoidMocapX.Core.Skeleton;

static class CcdIkTests
{
    internal static void Run()
    {
        var skeleton = Skeleton.Create(new[]
        {
            new BoneDefinition("root", null, XForm.Identity),
            new BoneDefinition("elbow", "root", new XForm(Vector3.UnitX, Quaternion.Identity)),
            new BoneDefinition("hand", "elbow", new XForm(Vector3.UnitY, Quaternion.Identity)),
            new BoneDefinition("finger", "hand", new XForm(Vector3.UnitY * .2f, Quaternion.CreateFromAxisAngle(Vector3.UnitX, .4f)))
        });
        var rest = skeleton.Bones.Select(b => b.RestLocal).ToArray();
        var solver = new CcdIk(skeleton, new[] { 0, 1 }, 2);
        var pose = (XForm[])rest.Clone();
        var residual = solver.Solve(pose, new Vector3(.7f, 1.3f, .4f), iterations: 128, tolerance: 1e-5f);
        MotionTests.Check(residual < 1e-4, $"CCD must reach a reachable target; residual {residual}");
        Invariants(rest, pose);
        pose = (XForm[])rest.Clone();
        residual = solver.Solve(pose, new Vector3(20, 0, 0), iterations: 128);
        MotionTests.Near(18, residual, .001);
        Invariants(rest, pose);

        var locked = (XForm[])rest.Clone();
        var limits = new LockedJoint(rest);
        solver.Solve(locked, new Vector3(-1, 1, 0), constrain: limits.Apply);
        MotionTests.Near(0, MathQ.AngleBetween(rest[0].Rot, locked[0].Rot), 1e-6);
        MotionTests.Check(limits.Calls > 0, "CCD must enforce the supplied joint constraint");

        var offsetSolver = new CcdIk(skeleton, new[] { 0 }, 2);
        var offset = new Vector3(.1f, .3f, 0);
        var offsetGoal = Vector3.Transform(new Vector3(1, 1, 0) + offset,
            Quaternion.CreateFromAxisAngle(Vector3.UnitZ, .4f));
        pose = (XForm[])rest.Clone();
        MotionTests.Check(offsetSolver.Solve(pose, offsetGoal, tipOffset: offset) < .001f, "CCD tip offset must reach the target");

        Reject(() => new CcdIk(skeleton, new[] { 1, 0 }, 2));
        Reject(() => new CcdIk(skeleton, new[] { -1 }, 2));
        Reject(() => solver.Solve(rest, new Vector3(float.NaN, 0, 0)));
        Reject(() => solver.Solve(rest, Vector3.Zero, iterations: 0));
        Reject(() => solver.Solve(rest, Vector3.Zero, gain: float.NaN));
        var invalid = (XForm[])rest.Clone(); invalid[1].Rot = default;
        Reject(() => solver.Solve(invalid, Vector3.Zero));

        pose = (XForm[])rest.Clone();
        for (var i = 0; i < 10; i++) solver.Solve(pose, new Vector3(.7f, 1.3f, .4f));
        var before = GC.GetAllocatedBytesForCurrentThread();
        for (var i = 0; i < 100; i++) solver.Solve(pose, new Vector3(.7f, 1.3f, .4f));
        MotionTests.Check(GC.GetAllocatedBytesForCurrentThread() == before, "CCD solve must not allocate");
        Console.WriteLine("PASS: DigitalRune CCD adaptation, reach residuals, constraints, offsets, validation and zero-allocation solve");
    }

    static void Invariants(XForm[] before, XForm[] after)
    {
        for (var i = 0; i < before.Length; i++) MotionTests.Near(0, Vector3.Distance(before[i].Pos, after[i].Pos));
        for (var i = 2; i < before.Length; i++) MotionTests.Near(0, MathQ.AngleBetween(before[i].Rot, after[i].Rot));
    }

    static void Reject(Action action)
    {
        try { action(); } catch (ArgumentException) { return; }
        throw new Exception("CCD accepted an invalid chain or input");
    }

    sealed class LockedJoint(XForm[] reference)
    {
        internal int Calls;
        internal void Apply(XForm[] pose, int bone) { Calls++; if (bone == 0) pose[bone].Rot = reference[bone].Rot; }
    }
}
notpointless.chomnr_humanoid_mocap_x / Editor/Server/EditorHost.cs
Editor library
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Editor;
using HumanoidMocapX.EditorTools.Video;
using HumanoidMocapX;
using HumanoidMocapX.EditorTools;
using Sandbox;

namespace HumanoidMocapHost;

/// <summary>Opt-in processing host inside the s&amp;box editor. Operator configuration
/// comes from MOCAP_* environment variables; see docs/editor-host.md.</summary>
public static class EditorHost
{
    // The engine exposes static console/event entry points; session state stays here.
    static readonly SemaphoreSlim Changes = new(1, 1);
    static EditorHostLifetime active;
    static CancellationTokenSource starting;

    /// <summary>Verifies installed Base/Latest weights, then listens on loopback. Requires
    /// Windows Media Foundation and a GPU budget. Startup failures propagate to the console.</summary>
    [ConCmd("mocap_x_host_start", ConVarFlags.Protected, Help = "Start the configured in-editor Humanoid Mocap X processing host")]
    public static async Task StartAsync()
    {
        await Changes.WaitAsync();
        using var cancellation = new CancellationTokenSource();
        starting = cancellation;
        try
        {
            if (active is { IsRunning: true }) { Log.Info("Humanoid Mocap X host is already running."); return; }
            if (active is not null) { await active.StopAsync(); active = null; }
            if (LocalCapture.Availability is { } reason) throw new PlatformNotSupportedException(reason);
            var config = HostConfiguration.Read(Environment.GetEnvironmentVariable,
                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "HumanoidMocapX"));
            await ModelStore.InstalledAsync(config.Models, FlowModel.Base, message => Log.Info(message), cancellation.Token);
            await ModelStore.InstalledAsync(config.Models, FlowModel.Latest, message => Log.Info(message), cancellation.Token);
            await GameTask.MainThread(); cancellation.Token.ThrowIfCancellationRequested();
            if (!Graphics.IsAvailable || Graphics.VideoMemoryBudget == 0 && Sandbox.Engine.SystemInfo.GpuMemory == 0)
                throw new InvalidOperationException("The host needs an initialized GPU with a reported video-memory budget.");
            active = Start(config);
            Log.Info($"Humanoid Mocap X host listening on http://127.0.0.1:{config.Port}/. Stop with mocap_x_host_stop.");
        }
        finally { starting = null; Changes.Release(); }
    }

    static EditorHostLifetime Start(HostConfiguration config)
    {
        var lanes = config.Lanes == CaptureLanes.Auto ? CaptureLanes.Maximum : config.Lanes;
        var admission = new GpuAdmission(lanes);
        admission.Update(Graphics.VideoMemoryBudget, Graphics.VideoMemoryUsed, Sandbox.Engine.SystemInfo.GpuMemory);
        var storage = new FileJobStorage(config.Data);
        try
        {
            var processor = new CaptureProcessor(storage.CaptureDirectory, config.UploadBytes,
                (selected, workspace, progress) => new LocalCapture(new CaptureOptions
                { Model = selected.Model, CameraInterval = selected.CameraInterval, Lanes = lanes }, config.Models, workspace, progress),
                ReadDurationAsync);
            var queue = new CaptureQueue(storage, processor, TimeProvider.System, config.ActivePerOwner,
                maximumUploadBytes: config.UploadBytes, maximumClipSeconds: config.ClipSeconds,
                concurrentJobs: config.ConcurrentJobs, canStartJob: admission.CanStart);
            var session = new HostSession($"http://127.0.0.1:{config.Port}/", config.Keys, storage, queue, ReportError);
            return new EditorHostLifetime(session, admission);
        }
        catch { storage.Dispose(); throw; }
    }

    static Task<double> ReadDurationAsync(string video, CancellationToken token) => Task.Run(() =>
    {
        token.ThrowIfCancellationRequested();
        using var decoder = IVideoDecoder.Open(video);
        return decoder.Duration;
    }, token);

    /// <summary>Cancels startup, uploads and active captures, then waits for GPU cleanup.
    /// Repeated calls are safe; completed job IDs are invalidated by the next start.</summary>
    [ConCmd("mocap_x_host_stop", ConVarFlags.Protected, Help = "Stop and drain the in-editor Humanoid Mocap X processing host")]
    public static async Task StopAsync()
    {
        try { starting?.Cancel(); } catch (ObjectDisposedException) { } // Startup just finished.
        await Changes.WaitAsync();
        try
        {
            await GameTask.MainThread();
            if (active is not null) { await active.StopAsync(); active = null; }
        }
        finally { Changes.Release(); }
    }

    [EditorEvent.Hotload]
    static void Hotloaded() => _ = StopAfterHotloadAsync();

    static async Task StopAfterHotloadAsync()
    {
        try { await StopAsync(); }
        catch (Exception error) { ReportError(error); }
    }

    static void ReportError(Exception error) => Log.Error($"Humanoid Mocap X host: {error}");
}
notpointless.chomnr_humanoid_mocap_x / Editor/Server/HostSession.cs
Editor library
#nullable enable annotations

using System;
using System.Threading;
using System.Threading.Tasks;

namespace HumanoidMocapHost;

/// <summary>Owns one HTTP listener, queue loop and file-store lifetime. Shutdown drains
/// uploads and GPU captures before disposing their resources.</summary>
internal sealed class HostSession : IAsyncDisposable
{
    readonly object gate = new();
    readonly CancellationTokenSource stopping = new();
    readonly FileJobStorage storage;
    readonly CaptureQueue queue;
    readonly HttpHost http;
    readonly Task worker;
    readonly Action<Exception> reportError;
    Task? shutdown;
    internal bool IsStopping { get { lock (gate) return shutdown is not null; } }

    internal HostSession(string prefix, ApiKeys keys, FileJobStorage storage, CaptureQueue queue, Action<Exception> reportError)
    {
        this.storage = storage; this.queue = queue; this.reportError = reportError;
        try { http = new HttpHost(prefix, keys, queue, reportError); }
        catch { stopping.Dispose(); queue.Dispose(); storage.Dispose(); throw; }
        worker = Task.Run(() => QueueLoop.RunAsync(queue, (id, error) => reportError(new InvalidOperationException($"Capture {id} failed.", error)), stopping.Token));
        _ = ObserveAsync();
    }

    async Task ObserveAsync()
    {
        try { await worker; }
        catch (Exception error) { reportError(error); }
        finally
        {
            try { await StopAsync(); }
            catch (Exception error) { reportError(error); }
        }
    }

    /// <summary>Idempotently stops this instance. The returned task completes only after
    /// cancellation and resource cleanup; callers must await it before starting a replacement.</summary>
    internal Task StopAsync()
    {
        lock (gate) return shutdown ??= StopCoreAsync();
    }

    async Task StopCoreAsync()
    {
        await stopping.CancelAsync();
        try { await http.DisposeAsync(); }
        finally
        {
            try { await worker; }
            finally
            {
                try { queue.Dispose(); }
                finally
                {
                    try { storage.DeleteRun(); }
                    finally { storage.Dispose(); stopping.Dispose(); }
                }
            }
        }
    }

    public ValueTask DisposeAsync() => new(StopAsync());
}
Debug: View Raw JSON Response
{
    "TotalCount": 609,
    "Files": [
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "FlowSampler.cs",
            "FileName": "FlowSampler.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "// C# adaptation of FlowHMR's x1 Euler sampling. See THIRD_PARTY_NOTICES.md.\nusing System;\nusing System.Threading;\n\nnamespace HumanoidMocapX;\n\n/// <summary>Predicts the clean 491-channel motion latent at a normalized time in [0,1).\n/// Writes every output element; failures and cancellation propagate.</summary>\npublic delegate void FlowPrediction(ReadOnlySpan<float> state, float time, Span<float> output, CancellationToken cancellation);\n\n/// <summary>The released Base and Latest models use twenty Euler steps and x1 prediction.</summary>\npublic static class FlowSampler\n{\n    public const int Channels = 491;\n    public const int Steps = 20;\n\n    /// <summary>Replaces caller-supplied initial noise with sampled motion using a reusable\n    /// prediction buffer. Rejects invalid shapes and non-finite predictions. A failed or\n    /// cancelled run may leave state partially advanced; it must not be exported.</summary>\n    public static void Sample(float[] state, float[] prediction, FlowPrediction predict,\n        CancellationToken cancellation = default)\n    {\n        ArgumentNullException.ThrowIfNull(state);\n        ArgumentNullException.ThrowIfNull(prediction);\n        ArgumentNullException.ThrowIfNull(predict);\n        if (state.Length == 0 || state.Length % Channels != 0 || state.Length / Channels > FlowMotion.MaximumFrames\n            || prediction.Length != state.Length || ReferenceEquals(state, prediction))\n            throw new ArgumentException(\"Sampling needs separate, equally sized [frames,491] state and prediction buffers.\");\n        CheckFinite(state);\n        const float minimumRemaining = 1f / Steps;\n        for (var step = 0; step < Steps; step++)\n        {\n            cancellation.ThrowIfCancellationRequested();\n            var time = step / (float)Steps;\n            var delta = (step + 1) / (float)Steps - time;\n            predict(state, time, prediction, cancellation);\n            cancellation.ThrowIfCancellationRequested();\n            CheckFinite(prediction);\n            var remaining = Math.Max(1f - time, minimumRemaining);\n            for (var i = 0; i < state.Length; i++)\n                state[i] += (prediction[i] - state[i]) / remaining * delta;\n            CheckFinite(state);\n        }\n    }\n\n    static void CheckFinite(ReadOnlySpan<float> values)\n    {\n        foreach (var value in values)\n            if (!float.IsFinite(value)) throw new ArithmeticException(\"FlowHMR sampling produced or received a non-finite latent.\");\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HostedCaptureOptions.cs",
            "FileName": "HostedCaptureOptions.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\n\nnamespace HumanoidMocapX;\n\n/// <summary>Video-range and model settings sent to a processing host. Times are source seconds.</summary>\npublic sealed record HostedCaptureOptions(FlowModel Model, int CameraInterval, double Start, double? End)\n{\n    /// <summary>Rejects unsupported models, sampling intervals and invalid time ranges.</summary>\n    public void Validate()\n    {\n        new CaptureOptions { Model = Model, CameraInterval = CameraInterval }.Validate();\n        if (!double.IsFinite(Start) || Start < 0 || End is double end && (!double.IsFinite(end) || end <= Start))\n            throw new ArgumentException(\"The video range needs a finite, nonnegative start and a later end.\");\n    }\n}\n\n/// <summary>Protocol version, processor readiness, the upload limit in bytes, how many unfinished\n/// jobs one account may have, how many jobs wait and run across all accounts, how many process at\n/// once, and the longest video range in seconds. A provider's site reports the signed-in account's\n/// own limits and whether its jobs wait in the priority queue.</summary>\npublic sealed record HostedCapabilities(int Protocol, bool ProcessingAvailable, long MaximumUploadBytes,\n    int MaximumActiveJobs = 1, int QueueLength = 0, int Processing = 0, int ConcurrentJobs = 1,\n    double? MaximumClipSeconds = null, bool Priority = false);\n\n/// <summary>Job state returned by the host. QueuePosition is one-based while queued, out of\n/// QueueLength waiting jobs; Progress (0 to 1) is set while processing. SecondsUntilStart and\n/// SecondsRemaining are the host's estimates. ExpiresAt is when a finished job and its result\n/// are deleted. Priority jobs wait ahead of the others. IDs are opaque; result URLs are derived locally.</summary>\n#nullable enable annotations\npublic sealed record HostedJob(Guid Id, string State, string Message, int? QueuePosition = null, string? Name = null,\n    DateTimeOffset CreatedAt = default, int QueueLength = 0, double? Progress = null, int? SecondsUntilStart = null,\n    int? SecondsRemaining = null, DateTimeOffset? ExpiresAt = null, bool Priority = false);\n#nullable restore\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Formats/Fbx/FbxImportOptions.cs",
            "FileName": "FbxImportOptions.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Collections.Generic;\nusing System.Numerics;\nusing System.Threading;\nusing HumanoidMocapX.Core.Maths;\nusing HumanoidMocapX.Core.Skeleton;\n\nnamespace HumanoidMocapX.Core.Formats.Fbx;\n\nusing Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)\n\n/// <summary>Options for <see cref=\"FbxImporter.Import\"/>.</summary>\npublic sealed class FbxImportOptions\n{\n    /// <summary>Fixed resampling rate for all clips, frames per second.</summary>\n    public float SampleFps { get; init; } = 30f;\n    public long MaximumTransformSamples { get; init; } = long.MaxValue;\n    public CancellationToken CancellationToken { get; init; }\n\n    /// <summary>\n    /// When the static rest pose is degenerate (Mixamo-style zeroed bind translations) and no\n    /// usable BindPose node exists, sample frame 0 of the first clip as the rest pose.\n    /// </summary>\n    public bool RestFromFrame0WhenBindDegenerate { get; init; } = true;\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Formats/Fbx/FbxTransform.cs",
            "FileName": "FbxTransform.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Numerics;\nusing HumanoidMocapX.Core.Maths;\n\nnamespace HumanoidMocapX.Core.Formats.Fbx;\n\nusing Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)\n\n/// <summary>\n/// Per-node FBX local-transform evaluation: the static pivot/pre-rotation data of one Model\n/// plus the full FBX transform formula.\n/// </summary>\n/// <remarks>\n/// The FBX SDK formula (column-vector convention, right-multiply children):\n/// <code>\n/// World = ParentWorld \u00b7 T \u00b7 Roff \u00b7 Rp \u00b7 Rpre \u00b7 R \u00b7 Rpost\u207b\u00b9 \u00b7 Rp\u207b\u00b9 \u00b7 Soff \u00b7 Sp \u00b7 S \u00b7 Sp\u207b\u00b9\n/// </code>\n/// System.Numerics matrices are row-vector (<c>p' = p\u00b7M</c>), so the local matrix is composed\n/// in reverse order with row-form factors:\n/// <code>\n/// Local = T(-Sp)\u00b7S\u00b7T(Sp)\u00b7T(Soff)\u00b7T(-Rp)\u00b7R(Rpre\u00b7R\u00b7Rpost\u207b\u00b9)\u00b7T(Rp)\u00b7T(Roff)\u00b7T(t)\n/// World = Local \u00b7 ParentWorld\n/// </code>\n/// <para><b>RotationOrder</b> (0=XYZ, 1=XZY, 2=YZX, 3=YXZ, 4=ZXY, 5=ZYX): the letters give the\n/// application order, first letter applied first \u2014 eEulerXYZ composes <c>R = Rz\u00b7Ry\u00b7Rx</c> in\n/// column convention (verified against Blender-imported ground truth of Mixamo and citizen\n/// rigs). Pre/Post rotations always use XYZ order and are only applied when\n/// <c>RotationActive</c> is set (matching Blender's importer; defaults to active when the\n/// property is absent everywhere).</para>\n/// <para><b>InheritType</b> (0=RrSs, 1=RSrs, 2=Rrs): scale is dropped to rigid transforms by\n/// this importer \u2014 world matrices are evaluated with full scale, then decomposed to pos+rot\n/// with scale folded into child translations \u2014 so types 0 and 1 are handled identically.\n/// Files that use non-uniform scale meaningfully with InheritType 2 (no parent scale\n/// propagation) are evaluated as type 0; this is a documented limitation.</para>\n/// </remarks>\npublic sealed class FbxTransform\n{\n    /// <summary>Static \"Lcl Translation\" default (native units).</summary>\n    public Vector3 LclTranslation { get; init; }\n\n    /// <summary>Static \"Lcl Rotation\" default, euler degrees in <see cref=\"RotationOrder\"/>.</summary>\n    public Vector3 LclRotationDeg { get; init; }\n\n    /// <summary>Static \"Lcl Scaling\" default.</summary>\n    public Vector3 LclScaling { get; init; } = Vector3.One;\n\n    /// <summary>PreRotation as a quaternion (identity when inactive or absent).</summary>\n    public Quaternion PreRotation { get; init; } = Quaternion.Identity;\n\n    /// <summary>PostRotation as a quaternion (identity when inactive or absent).</summary>\n    public Quaternion PostRotation { get; init; } = Quaternion.Identity;\n\n    /// <summary>RotationOffset (Roff).</summary>\n    public Vector3 RotationOffset { get; init; }\n\n    /// <summary>RotationPivot (Rp).</summary>\n    public Vector3 RotationPivot { get; init; }\n\n    /// <summary>ScalingOffset (Soff).</summary>\n    public Vector3 ScalingOffset { get; init; }\n\n    /// <summary>ScalingPivot (Sp).</summary>\n    public Vector3 ScalingPivot { get; init; }\n\n    /// <summary>Euler application order code, 0=XYZ \u2026 5=ZYX (see class remarks).</summary>\n    public int RotationOrder { get; init; }\n\n    /// <summary>InheritType 0=RrSs, 1=RSrs, 2=Rrs (see class remarks for handling).</summary>\n    public int InheritType { get; init; }\n\n    /// <summary>Reads the static transform data of a Model from its (template-backed) properties.</summary>\n    public static FbxTransform FromModel(FbxScene scene, FbxObject model)\n    {\n        ArgumentNullException.ThrowIfNull(scene);\n        ArgumentNullException.ThrowIfNull(model);\n\n        // Pre/Post rotation participate only when RotationActive is set (Blender-compatible).\n        // When the property is absent on both the object and its template, default to active \u2014\n        // exporters that strip RotationActive but keep PreRotation expect it applied.\n        bool rotationActive = scene.FindProperty(model, \"RotationActive\") is { } ra\n            ? ra.GetInt() != 0\n            : true;\n\n        var pre = scene.GetVector3(model, \"PreRotation\", Vector3.Zero);\n        var post = scene.GetVector3(model, \"PostRotation\", Vector3.Zero);\n\n        return new FbxTransform\n        {\n            LclTranslation = scene.GetVector3(model, \"Lcl Translation\", Vector3.Zero),\n            LclRotationDeg = scene.GetVector3(model, \"Lcl Rotation\", Vector3.Zero),\n            LclScaling = scene.GetVector3(model, \"Lcl Scaling\", Vector3.One),\n            PreRotation = rotationActive ? EulerDegreesToQuaternion(pre, 0) : Quaternion.Identity,\n            PostRotation = rotationActive ? EulerDegreesToQuaternion(post, 0) : Quaternion.Identity,\n            RotationOffset = scene.GetVector3(model, \"RotationOffset\", Vector3.Zero),\n            RotationPivot = scene.GetVector3(model, \"RotationPivot\", Vector3.Zero),\n            ScalingOffset = scene.GetVector3(model, \"ScalingOffset\", Vector3.Zero),\n            ScalingPivot = scene.GetVector3(model, \"ScalingPivot\", Vector3.Zero),\n            RotationOrder = scene.GetInt(model, \"RotationOrder\", 0),\n            InheritType = scene.GetInt(model, \"InheritType\", 0),\n        };\n    }\n\n    /// <summary>\n    /// Local matrix (row-vector layout) for given TRS values; pass the Lcl defaults for the\n    /// rest pose or per-frame sampled values for animation.\n    /// </summary>\n    public Matrix4x4 LocalMatrix(Vector3 translation, Vector3 rotationDeg, Vector3 scaling)\n    {\n        // Column chain R-part: Rpre \u00b7 R \u00b7 Rpost\u207b\u00b9  \u2192  our quaternion convention (a*b applies\n        // b first) composes the same way.\n        var rotation = MathQ.Normalize(\n            PreRotation *\n            EulerDegreesToQuaternion(rotationDeg, RotationOrder) *\n            Quaternion.Conjugate(PostRotation));\n\n        // Row-vector composition, first-applied factor leftmost (see class remarks).\n        var m = Matrix4x4.CreateTranslation(-ScalingPivot);\n        m *= Matrix4x4.CreateScale(scaling);\n        m *= Matrix4x4.CreateTranslation(ScalingPivot + ScalingOffset - RotationPivot);\n        m *= Matrix4x4.CreateFromQuaternion(rotation);\n        m *= Matrix4x4.CreateTranslation(RotationPivot + RotationOffset + translation);\n        return m;\n    }\n\n    /// <summary>Local matrix from the static Lcl defaults (rest evaluation, no animation).</summary>\n    public Matrix4x4 LocalMatrixDefault() => LocalMatrix(LclTranslation, LclRotationDeg, LclScaling);\n\n    /// <summary>\n    /// Converts FBX euler angles (degrees) to a quaternion for the given RotationOrder code.\n    /// The order letters list the application sequence (XYZ = X first, then Y, then Z).\n    /// </summary>\n    public static Quaternion EulerDegreesToQuaternion(Vector3 degrees, int order)\n    {\n        const float degToRad = MathF.PI / 180f;\n        var qx = Quaternion.CreateFromAxisAngle(Vector3.UnitX, degrees.X * degToRad);\n        var qy = Quaternion.CreateFromAxisAngle(Vector3.UnitY, degrees.Y * degToRad);\n        var qz = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, degrees.Z * degToRad);\n\n        // q = third * second * first (our convention applies the right factor first).\n        return order switch\n        {\n            0 => qz * qy * qx, // XYZ\n            1 => qy * qz * qx, // XZY\n            2 => qx * qz * qy, // YZX\n            3 => qz * qx * qy, // YXZ\n            4 => qy * qx * qz, // ZXY\n            5 => qx * qy * qz, // ZYX\n            6 => qz * qy * qx, // eSphericXYZ \u2014 treated as XYZ\n            _ => throw new FormatException($\"Unsupported FBX RotationOrder {order}.\"),\n        };\n    }\n\n    /// <summary>\n    /// Extracts the rigid part of a (possibly scaled) world matrix: translation taken directly,\n    /// rotation from the orthonormalized basis. Scale is thereby folded into child translations\n    /// when parent-relative transforms are derived from rigid worlds. Mirrored (negative\n    /// determinant) bases fall back to the dominant proper rotation (best effort \u2014 mirrored\n    /// skeletons are not meaningfully supported).\n    /// </summary>\n    public static XForm ToRigid(in Matrix4x4 world)\n    {\n        var pos = world.Translation;\n\n        var x = new Vector3(world.M11, world.M12, world.M13);\n        var y = new Vector3(world.M21, world.M22, world.M23);\n        var z = new Vector3(world.M31, world.M32, world.M33);\n\n        x = SafeNormalize(x, Vector3.UnitX);\n        y = SafeNormalize(y, Vector3.UnitY);\n        z = SafeNormalize(z, Vector3.UnitZ);\n\n        // Mirrored basis: flip the third axis to restore a proper rotation.\n        if (Vector3.Dot(Vector3.Cross(x, y), z) < 0f)\n            z = -z;\n\n        var m = new Matrix4x4(\n            x.X, x.Y, x.Z, 0f,\n            y.X, y.Y, y.Z, 0f,\n            z.X, z.Y, z.Z, 0f,\n            0f, 0f, 0f, 1f);\n\n        return new XForm(pos, MathQ.Normalize(Quaternion.CreateFromRotationMatrix(m)));\n    }\n\n    private static Vector3 SafeNormalize(Vector3 v, Vector3 fallback)\n    {\n        float lsq = v.LengthSquared();\n        if (!float.IsFinite(lsq) || lsq < 1e-20f)\n            return fallback;\n        return v / MathF.Sqrt(lsq);\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Formats/Fbx/ModelDocFbxExport.cs",
            "FileName": "ModelDocFbxExport.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing HumanoidMocapX.Core.Maths;\nusing HumanoidMocapX.Core.Skeleton;\n\nnamespace HumanoidMocapX.Core.Formats.Fbx;\nusing SkeletonModel = HumanoidMocapX.Core.Skeleton.Skeleton;\n\n/// <summary>FBX with the source-to-engine scale baked into every translation for direct ModelDoc import.</summary>\npublic static class ModelDocFbxExport\n{\n\t/// <summary>Uses Humanoid Retargeter's source scale for centimetre rigs; compiled engine rigs already use inches.</summary>\n\tpublic static byte[] Write( SkeletonModel skeleton, string name, IReadOnlyList<XForm[]> frames,\n\t\tIReadOnlyList<double> times, double fps, TargetUpAxis axis, string motionSpace )\n\t{\n\t\tArgumentNullException.ThrowIfNull( skeleton );\n\t\tArgumentNullException.ThrowIfNull( frames );\n\t\tif ( frames.Count is < 1 or > 108000 || skeleton.Count is < 1 or > 1024\n\t\t\t|| (long)frames.Count * skeleton.Count > FbxAnimationWriter.MaximumTransformSamples )\n\t\t\tthrow new ArgumentException( \"Animation exceeds the export budget. Select a shorter range.\" );\n\t\tif ( axis is not (TargetUpAxis.YUpCm or TargetUpAxis.ZUpEngine) )\n\t\t\tthrow new ArgumentOutOfRangeException( nameof( axis ) );\n\n\t\t// Like Retargeter's ModelModifier_ScaleAndMirror, this converts raw source values.\n\t\t// UnitScaleFactor alone is insufficient for ModelDoc's raw-unit import. Bake the\n\t\t// factor into bind positions, all local translations, root motion and appended props.\n\t\tif ( axis == TargetUpAxis.YUpCm )\n\t\t{\n\t\t\tXForm Scale( XForm pose ) => new( pose.Pos * RetargetTargetSpec.SboxSourceScale, pose.Rot );\n\t\t\tskeleton = SkeletonModel.Create( skeleton.Bones.Select( bone => new BoneDefinition(\n\t\t\t\tbone.Name, bone.ParentIndex < 0 ? null : skeleton[ bone.ParentIndex ].Name,\n\t\t\t\tScale( bone.RestLocal ) ) ).ToArray() );\n\t\t\tframes = frames.Select( frame => frame.Select( Scale ).ToArray() ).ToArray();\n\t\t}\n\n\t\treturn FbxAnimationWriter.Write( skeleton, name, frames, times, fps,\n\t\t\taxis == TargetUpAxis.YUpCm ? 1 : 2, 2.54, motionSpace );\n\t}\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/InspectResult.cs",
            "FileName": "InspectResult.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing HumanoidMocapX.Core.Mapping;\nusing HumanoidMocapX.Core.Maths;\nusing HumanoidMocapX.Core.Target;\nusing HumanoidMocapX.Core.Skeleton;\n\nnamespace HumanoidMocapX.Core;\n\n/// <summary>\n/// Result of <see cref=\"Retargeter.Inspect\"/>: the mapping report plus the file's take\n/// metadata, so UI listings can expand a multi-take file into one entry per take (each\n/// convertible independently via <see cref=\"RetargetRequest.TakeIndex\"/>).\n/// </summary>\npublic sealed class InspectResult\n{\n    /// <summary>Mapping report from the same preset-then-auto cascade conversion uses.</summary>\n    public required MappingReportInfo Mapping { get; init; }\n\n    /// <summary>Names of the file's animation takes, in take-index order (the index is what\n    /// <see cref=\"RetargetRequest.TakeIndex\"/> accepts). Empty when the file has no animation.</summary>\n    public required IReadOnlyList<string> TakeNames { get; init; }\n\n    /// <summary>Number of animation takes in the file.</summary>\n    public int TakeCount => TakeNames.Count;\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Motion/ArmSettings.cs",
            "FileName": "ArmSettings.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\nusing System.Numerics;\nusing HumanoidMocapX.Core.Maths;\n\nnamespace HumanoidMocapX.Core.Motion;\nusing Vector3 = System.Numerics.Vector3;\n\npublic sealed class ArmSettings\n{\n    public Vector3 Shoulder { get; set; } = new(.18f,-.15f,0);\n    public Vector3 ElbowTarget { get; set; } = new(.4f,-.4f,.2f);\n    public float UpperLength { get; set; } = .28f;\n    public float ForearmLength { get; set; } = .25f;\n    public float MaximumReach { get; set; } = .995f;\n    public float MinimumElbowDegrees { get; set; } = 5;\n    public float MaximumElbowDegrees { get; set; } = 155;\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Motion/CaptureLegReach.cs",
            "FileName": "CaptureLegReach.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\n\nnamespace HumanoidMocapX.Core.Motion;\n\nusing Vector3 = System.Numerics.Vector3;\n\n/// <summary>Leaves a small knee bend when moving the pelvis to reach captured foot targets.</summary>\ninternal static class CaptureLegReach\n{\n\t// Exact full extension is singular: a millimetre of ankle travel can unfold the knee\n\t// by centimetres. Reserve half a percent of reach and enter the correction smoothly.\n\tinternal const float ReachFraction = .995f;\n\n\tinternal static float Lowering( Vector3 hipToFoot, Vector3 up, float length )\n\t{\n\t\tvar vertical = Vector3.Dot( hipToFoot, up );\n\t\tvar horizontal = hipToFoot - up * vertical;\n\t\tvar reach = length * ReachFraction;\n\t\tif ( length <= 0 || vertical <= 0 || horizontal.LengthSquared() >= reach * reach ) return 0;\n\n\t\tvar deficit = vertical - MathF.Sqrt( reach * reach - horizontal.LengthSquared() );\n\t\tvar ease = length * .01f;\n\t\t// Smooth positive part, evaluated without subtracting two nearly equal numbers.\n\t\tvar diagonal = MathF.Sqrt( deficit * deficit + ease * ease );\n\t\treturn deficit >= 0 ? (deficit + diagonal) * .5f : ease * ease / (2 * (diagonal - deficit));\n\t}\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Preview/PreviewFrameBuffer.cs",
            "FileName": "PreviewFrameBuffer.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\n\nnamespace HumanoidMocapX.Core.Preview;\n\n/// <summary>Owns a bounded RGBA preview frame. Reuses storage until the preview size\n/// changes; callers must synchronize concurrent readers and writers.</summary>\npublic sealed class PreviewFrameBuffer\n{\n    const int MaximumWidth = 960, MaximumHeight = 540, PixelBytes = 4;\n    byte[] pixels = Array.Empty<byte>();\n    /// <summary>Width of the owned preview in pixels; zero before the first frame.</summary>\n    public int Width { get; private set; }\n    /// <summary>Height of the owned preview in pixels; zero before the first frame.</summary>\n    public int Height { get; private set; }\n    /// <summary>Increases after each successful copy so consumers can skip unchanged frames.</summary>\n    public long Version { get; private set; }\n    /// <summary>Borrowed pixels, valid until the next Copy call.</summary>\n    public ReadOnlySpan<byte> Pixels => pixels;\n\n    /// <summary>Copies a packed RGBA frame, reducing it to fit 960\u00d7540 without changing\n    /// aspect ratio. Rejects nonpositive dimensions and an incorrect byte count.</summary>\n    public void Copy(ReadOnlySpan<byte> source, int width, int height)\n    {\n        if (width < 1 || height < 1 || (long)width * height * PixelBytes != source.Length)\n            throw new ArgumentException(\"Video preview requires a complete packed RGBA frame.\");\n        var scale = Math.Min(1, Math.Min((double)MaximumWidth / width, (double)MaximumHeight / height));\n        var targetWidth = Math.Max(1, (int)(width * scale));\n        var targetHeight = Math.Max(1, (int)(height * scale));\n        var length = targetWidth * targetHeight * PixelBytes;\n        if (pixels.Length != length) pixels = new byte[length];\n        if (targetWidth == width && targetHeight == height) source.CopyTo(pixels);\n        else\n            for (var y = 0; y < targetHeight; y++)\n                for (var x = 0; x < targetWidth; x++)\n                {\n                    var from = ((long)y * height / targetHeight * width + (long)x * width / targetWidth) * PixelBytes;\n                    var to = (y * targetWidth + x) * PixelBytes;\n                    source.Slice((int)from, PixelBytes).CopyTo(pixels.AsSpan(to, PixelBytes));\n                }\n        Width = targetWidth; Height = targetHeight; Version++;\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Retargeter.cs",
            "FileName": "Retargeter.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Collections.Generic;\nusing System.Numerics;\nusing System.Text;\nusing HumanoidMocapX.Core.Cleanup;\nusing HumanoidMocapX.Core.Formats;\nusing HumanoidMocapX.Core.Formats.Dmx;\nusing HumanoidMocapX.Core.Formats.Fbx;\nusing HumanoidMocapX.Core.Formats.Gltf;\nusing HumanoidMocapX.Core.Mapping;\nusing HumanoidMocapX.Core.Maths;\nusing HumanoidMocapX.Core.Skeleton;\nusing HumanoidMocapX.Core.Solve;\nusing HumanoidMocapX.Core.Target;\nusing SkeletonModel = HumanoidMocapX.Core.Skeleton.Skeleton;\n\nnamespace HumanoidMocapX.Core;\n\nusing Vector3 = System.Numerics.Vector3; // s&box compat: shadow engine's global-namespace Vector3 (see Code/HumanoidMocap/Assembly.cs)\n\n/// <summary>\n/// Engine-agnostic pipeline facade (design \u00a75): bytes in \u2192 DMX + vmdl text out. Composes\n/// import \u2192 mapping \u2192 solve \u2192 cleanup \u2192 IK baking \u2192 DMX \u2192 vmdl assembly. Batch is\n/// first-class: N files \u00d7 all takes per file \u2192 ONE combined vmdl, with per-request profile\n/// detection (a batch may mix Mixamo + ActorCore + BVH sources) and per-clip failure\n/// isolation. No file IO anywhere in this type \u2014 callers pass bytes/strings and write the\n/// returned strings.\n/// </summary>\n/// <remarks>\n/// Pipeline per clip:\n/// <list type=\"number\">\n/// <item><b>Import</b> \u2014 format by file extension (<c>.hmotion</c>/<c>.fbx</c>/<c>.glb</c>/\n/// <c>.gltf</c>/<c>.vrm</c>), content sniff as fallback \u2192 <see cref=\"SourceScene\"/> (cm,\n/// native axes).</item>\n/// <item><b>Mapping</b> \u2014 per request: <see cref=\"RetargetRequest.MappingOverride\"/> wins;\n/// else <see cref=\"ProfileDetector.Detect\"/> over the preset library (user presets are\n/// loaded Editor-side and arrive as overrides); else <see cref=\"AutoMapper.Map\"/> as best\n/// effort with <see cref=\"MappingReportInfo.NeedsUserDecision\"/> set when its confidence is\n/// below <see cref=\"ProfileDetector.DetectionThreshold\"/>.</item>\n/// <item><b>Solve</b> \u2014 <see cref=\"GeometricSolver\"/> per take (clip name = take name, or\n/// <see cref=\"RetargetRequest.ClipNameOverride\"/> + index).</item>\n/// <item><b>Cleanup</b> (target space) \u2014 <see cref=\"FootPlant\"/> when enabled (chains from\n/// the target rig's UpperLeg/LowerLeg/Foot/Toe roles, up axis from the TARGET character\n/// frame, fps from the clip); optional arm <see cref=\"EffectorIk\"/> (off by default \u2014 the\n/// solver already matches anatomical directions); <see cref=\"RootMotion\"/> per mode (see\n/// below).</item>\n/// <item><b>IK baking</b> \u2014 <see cref=\"IkBoneBaker.Bake\"/> when the rig has\n/// <see cref=\"BoneClass.IkBaked\"/> bones.</item>\n/// <item><b>DMX</b> \u2014 <see cref=\"DmxWriter\"/> over the target skeleton.</item>\n/// <item><b>Assembly</b> \u2014 <see cref=\"VmdlWriter.GenerateStandalone\"/> over all successful\n/// clips, plus <see cref=\"VmdlAugmenter.Augment\"/> when\n/// <see cref=\"BatchOptions.AugmentVmdlText\"/> is provided; clip-name collisions are\n/// auto-suffixed (<c>_2</c>, <c>_3</c>, \u2026) across the batch.</item>\n/// </list>\n/// <para><b>Root-motion \u2194 target mapping.</b> <see cref=\"RootMotionMode.Extract\"/> bakes the\n/// ground-projected hips path onto the target's dedicated root bone \u2014 defined as a parentless\n/// <see cref=\"BoneClass.Animated\"/> bone that is an ancestor of (and distinct from) the Hips\n/// bone. The s&amp;box rig has NO such bone (pelvis is itself parentless; root_IK is IkBaked),\n/// so there Extract leaves the frames untouched, adds a report note, and instead sets\n/// <see cref=\"AnimEntry.ExtractMotion\"/> on the clip's vmdl entry: Source 2 extracts the\n/// ground-plane translation from <see cref=\"RetargetTargetSpec.DefaultRootBone\"/> at compile\n/// time, which is the engine-native equivalent. The ExtractMotion flag is set for every\n/// Extract request either way. <see cref=\"RootMotionMode.InPlace\"/> always operates on the\n/// hips channels directly and needs no dedicated root.</para>\n/// </remarks>\npublic static class Retargeter\n{\n\t/// <summary>\n\t/// Applies the same mapping, diagnostics, and mid-pose bind-rest selection used by\n\t/// <see cref=\"ConvertBatch\"/>, while leaving the sampled clips available to an editor\n\t/// integration that needs an in-memory target rather than DMX output.\n\t/// </summary>\n\tpublic static ResolvedSource ResolveSource( SourceScene scene, MappingResult? mappingOverride = null,\n\t\tFunc<string, MappingResult?>? userPresetLookup = null )\n\t{\n\t\tArgumentNullException.ThrowIfNull( scene );\n\t\tvar (map, report) = ResolveMapping( scene.Skeleton, mappingOverride, userPresetLookup, scene.AuthoredMapping );\n\t\tforeach ( var note in scene.Notes ) AddNote( report, note );\n\t\tscene = MaybeAdoptBindRest( scene, map, report );\n\t\treturn new( scene, map, report );\n\t}\n\n    /// <summary>Converts one source file \u2014 all takes, or only\n    /// <see cref=\"RetargetRequest.TakeIndex\"/> when set. Equivalent to a one-request batch.</summary>\n    public static RetargetResult Convert(RetargetRequest request, RetargetTargetSpec target)\n    {\n        ArgumentNullException.ThrowIfNull(request);\n        var batch = ConvertBatch(new[] { request }, target);\n        return new RetargetResult\n        {\n            Clips = batch.Clips,\n            StandaloneVmdl = batch.StandaloneVmdl,\n            Errors = batch.Errors,\n        };\n    }\n\n    /// <summary>\n    /// Converts a batch of source files against one target. Per-request profile detection,\n    /// per-clip failure isolation (a bad file yields a failed <see cref=\"ClipResult\"/> and\n    /// the batch continues), one standalone vmdl with every successful clip, optional\n    /// augmentation of an existing vmdl.\n    /// </summary>\n    public static RetargetBatchResult ConvertBatch(\n        IReadOnlyList<RetargetRequest> requests, RetargetTargetSpec target, BatchOptions? options = null)\n    {\n        ArgumentNullException.ThrowIfNull(requests);\n        ArgumentNullException.ThrowIfNull(target);\n        options ??= new BatchOptions();\n\n        var context = new TargetContext(target.Rig);\n        var result = new RetargetBatchResult();\n        var usedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);\n        var entries = new List<AnimEntry>();\n\n        // Augment mode: names already taken in the existing vmdl's AnimationList must not be\n        // silently repointed \u2014 seed the collision set with every existing node name EXCEPT\n        // our own AnimFiles (source_filename under DmxFolderRelative), which are replaceable\n        // so re-running the same batch stays idempotent.\n        if (options.AugmentVmdlText is not null)\n            SeedUsedNamesFromExistingVmdl(options.AugmentVmdlText, options.DmxFolderRelative, usedNames);\n\n        var mappedPinky = false;\n        foreach (var request in requests)\n        {\n            if (request is null)\n                continue;\n            mappedPinky |= ProcessRequest(\n                request, target, context, options, usedNames, result.Clips, entries);\n        }\n\n        foreach (var clip in result.Clips)\n        {\n            if (!clip.Success)\n                result.Errors.Add($\"{clip.SourceFileName}: {clip.Error}\");\n        }\n\n        // Locomotion families are detected on the FINAL (collision-suffixed) clip names so\n        // the blend grids reference exactly what the vmdl registers; folder/blend names are\n        // made unique against the same name set the clips used.\n        IReadOnlyList<LocomotionSetSpec>? locomotionSets = null;\n        if (options.DetectLocomotionSets)\n        {\n            var (sets, reports) = LocomotionSetDetector.Detect(\n                entries, usedNames, options.AutoSuffixCollisions);\n            result.LocomotionSets.AddRange(reports);\n            if (sets.Count > 0)\n                locomotionSets = sets;\n        }\n\n        // The target's OWN embedded animations ride along every generated vmdl (an FBX\n        // picked as target keeps its animation next to the retargeted ones). Skipped when\n        // a same-named entry is already registered (idempotent re-runs / augment targets\n        // that carry them from an earlier conversion); the retargeted clips claimed their\n        // names first, so an embedded take never displaces a converted clip.\n        if (target.ExtraAnimFiles is { Count: > 0 })\n        {\n            foreach (var extra in target.ExtraAnimFiles)\n            {\n                if (usedNames.Add(extra.Name))\n                    entries.Add(extra);\n            }\n        }\n\n        result.StandaloneVmdl = VmdlWriter.GenerateStandalone(\n            target.BaseModelPath, entries, target.VmdlScale, target.DefaultRootBone,\n            locomotionSets, target.MeshFilePath, target.MeshImportScale, target.MaterialRemaps,\n            target.MeshImportNames);\n\n        if (options.AugmentVmdlText is not null)\n        {\n            try\n            {\n                var removedSequences = new List<string>();\n                result.AugmentedVmdl = VmdlAugmenter.Augment(\n                    options.AugmentVmdlText, entries, out _,\n                    new AugmentOptions\n                    {\n                        DefaultRootBone = target.DefaultRootBone,\n                        // The citizen base model copies ring\u2192pinky via its CopyPinky\n                        // constraints; when this batch actually drives the pinky, the\n                        // augmented vmdl must neutralize them or the exported pinky\n                        // channels get overridden at runtime.\n                        NeutralizePinkyConstraints = mappedPinky,\n                        LocomotionSets = locomotionSets,\n                        // Same ownership rule the name seeding above used: pipeline-owned\n                        // locomotion folders (every AnimFile sourced under our DMX folder)\n                        // are replaceable wholesale on re-runs.\n                        DmxFolderRelative = options.DmxFolderRelative,\n                        // Stale entries whose DMX the caller found missing on disk: keep\n                        // them and the WHOLE vmdl stops compiling (\"Node 'X' resolve\n                        // failure\"), new sequences included.\n                        MissingSourceFiles = options.MissingAnimSources,\n                    },\n                    removedSequences);\n                foreach (var name in removedSequences)\n                {\n                    result.Warnings.Add(\n                        $\"removed stale sequence '{name}' from the augmented vmdl: its \"\n                        + \"animation source file no longer exists on disk (a missing source \"\n                        + \"fails the whole model recompile)\");\n                }\n            }\n            catch (Exception e)\n            {\n                result.Errors.Add($\"vmdl augmentation failed: {e.Message}\");\n            }\n        }\n\n        return result;\n    }\n\n    /// <summary>Collects names already present in the existing vmdl's AnimationList that the\n    /// batch must not reuse (everything except our own replaceable AnimFiles).</summary>\n    private static void SeedUsedNamesFromExistingVmdl(\n        string vmdlText, string dmxFolderRelative, HashSet<string> usedNames)\n    {\n        Kv3Document doc;\n        try\n        {\n            doc = Kv3.Parse(vmdlText);\n        }\n        catch (FormatException)\n        {\n            return; // the augmentation step itself surfaces the parse error\n        }\n\n        if (doc.Root is not KvObject root || root.GetOrNull(\"rootNode\") is not KvObject rootNode\n            || rootNode.GetOrNull(\"children\") is not KvArray children)\n            return;\n        var animList = children.Items.OfType<KvObject>()\n            .FirstOrDefault(o => o.GetString(\"_class\") == \"AnimationList\");\n        if (animList?.GetOrNull(\"children\") is not KvArray items)\n            return;\n\n        var folder = dmxFolderRelative.Replace('\\\\', '/').TrimEnd('/');\n        SeedNames(items, folder, usedNames);\n    }\n\n    /// <summary>\n    /// Recursive seeding step: every named AnimationList node reserves its name EXCEPT our\n    /// own replaceable output \u2014 AnimFiles whose source lives in the batch's DMX folder, and\n    /// locomotion Folders consisting entirely of such AnimFiles (a re-run replaces the whole\n    /// folder, so neither its name nor its content may block the new batch's names). Foreign\n    /// folders are seeded by name and their content seeded recursively.\n    /// </summary>\n    private static void SeedNames(KvArray items, string dmxFolder, HashSet<string> usedNames)\n    {\n        foreach (var node in items.Items.OfType<KvObject>())\n        {\n            var name = node.GetString(\"name\");\n            var cls = node.GetString(\"_class\");\n\n            if (cls == \"AnimFile\")\n            {\n                if (!string.IsNullOrEmpty(name) && !IsOurAnimFile(node, dmxFolder))\n                    usedNames.Add(name);\n                continue;\n            }\n\n            if (cls == \"Folder\")\n            {\n                if (IsOurLocomotionFolder(node, dmxFolder))\n                    continue; // replaceable wholesale \u2014 nothing inside reserves a name\n                if (!string.IsNullOrEmpty(name))\n                    usedNames.Add(name);\n                if (node.GetOrNull(\"children\") is KvArray nested)\n                    SeedNames(nested, dmxFolder, usedNames);\n                continue;\n            }\n\n            if (!string.IsNullOrEmpty(name))\n                usedNames.Add(name);\n        }\n    }\n\n    /// <summary>Whether an AnimFile was written by this pipeline: its source_filename sits\n    /// inside the batch's DMX folder.</summary>\n    private static bool IsOurAnimFile(KvObject node, string dmxFolder)\n    {\n        var source = (node.GetString(\"source_filename\") ?? \"\").Replace('\\\\', '/');\n        return dmxFolder.Length == 0\n            ? !source.Contains('/')\n            : source.StartsWith(dmxFolder + \"/\", StringComparison.OrdinalIgnoreCase);\n    }\n\n    /// <summary>Whether a Folder is a locomotion group this pipeline spliced: it contains at\n    /// least one AnimFile and every AnimFile inside it (recursively) is ours.</summary>\n    private static bool IsOurLocomotionFolder(KvObject folderNode, string dmxFolder)\n    {\n        var sawAnimFile = false;\n        return Walk(folderNode) && sawAnimFile;\n\n        bool Walk(KvObject node)\n        {\n            if (node.GetString(\"_class\") == \"AnimFile\")\n            {\n                sawAnimFile = true;\n                return IsOurAnimFile(node, dmxFolder);\n            }\n            if (node.GetOrNull(\"children\") is KvArray children)\n            {\n                foreach (var child in children.Items.OfType<KvObject>())\n                {\n                    if (!Walk(child))\n                        return false;\n                }\n            }\n            return true;\n        }\n    }\n\n    /// <summary>\n    /// Detection-only entry point for UI listings: imports the file and runs the same\n    /// preset-then-auto mapping as conversion, without solving anything. Also reports the\n    /// file's take metadata (clip names, in take-index order) so listings can expand a\n    /// multi-take file into one entry per take. Throws <see cref=\"FormatException\"/> when\n    /// the file is unreadable.\n    /// </summary>\n    public static InspectResult Inspect(byte[] sourceData, string fileName)\n    {\n        ArgumentNullException.ThrowIfNull(sourceData);\n        ArgumentNullException.ThrowIfNull(fileName);\n        var scene = ImportSource(sourceData, fileName);\n        var takeNames = new List<string>(scene.Clips.Count);\n        foreach (var clip in scene.Clips)\n            takeNames.Add(clip.Name);\n        return new InspectResult\n        {\n            Mapping = ResolveMapping(scene.Skeleton, authoredMapping: scene.AuthoredMapping).Report,\n            TakeNames = takeNames,\n        };\n    }\n\n    // ================================================================ per-request pipeline\n\n    /// <summary>Runs one request end to end. Returns true when at least one clip converted\n    /// successfully with a mapping that drives a pinky role (CopyPinky handling).</summary>\n    private static bool ProcessRequest(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        BatchOptions options, HashSet<string> usedNames,\n        List<ClipResult> clips, List<AnimEntry> entries)\n    {\n        var sourceId = request.SourceId ?? request.SourceFileName;\n        SourceScene scene;\n        MappingReportInfo report;\n        MappingResult map;\n        try\n        {\n            scene = ImportSource(\n                request.SourceData, request.SourceFileName, request.SampleFps,\n                request.ExternalBufferResolver);\n            (map, report) = ResolveMapping(\n                scene.Skeleton, request.MappingOverride, authoredMapping: scene.AuthoredMapping);\n            // Import diagnostics (mid-pose exports, cross-stack static disagreements, ...)\n            // ride the mapping report so UIs can surface them next to the conversion result.\n            foreach (var note in scene.Notes)\n                AddNote(report, note);\n            scene = MaybeAdoptBindRest(scene, map, report);\n        }\n        catch (Exception e)\n        {\n            clips.Add(new ClipResult\n            {\n                ClipName = FileStem(request.SourceFileName),\n                SourceFileName = request.SourceFileName,\n                SourceId = sourceId,\n                Success = false,\n                Error = e.Message,\n            });\n            return false;\n        }\n\n        if (scene.Clips.Count == 0)\n        {\n            clips.Add(new ClipResult\n            {\n                ClipName = FileStem(request.SourceFileName),\n                SourceFileName = request.SourceFileName,\n                SourceId = sourceId,\n                Mapping = report,\n                Success = false,\n                Error = \"Source file contains no animation takes.\",\n            });\n            return false;\n        }\n\n        var mapsPinky = MapsPinkyRole(map);\n        if (mapsPinky && options.AugmentVmdlText is null\n            && target.BaseModelPath == RetargetTargetSpec.SboxHumanMalePath)\n        {\n            // A standalone child vmdl cannot override the base model's AnimConstraintList:\n            // the citizen's CopyPinky (ring \u2192 pinky orient copy) keeps driving the pinky at\n            // runtime even though the DMX carries real pinky channels.\n            AddNote(report,\n                \"Pinky channels are exported, but the base model's CopyPinky constraints \"\n                + \"(ring \u2192 pinky copy) cannot be overridden from a standalone vmdl, so the \"\n                + \"pinky will visibly mirror the ring finger's motion in engine \u2014 use \"\n                + \"augment mode (add to the existing vmdl) to neutralize them.\");\n        }\n        if (target.UpAxis == TargetUpAxis.ZUpEngine)\n        {\n            AddNote(report,\n                \"Target rig is engine-space (Z-up, inches): the DMX declares a Z-up axis \"\n                + \"system so resourcecompiler performs no Y-up conversion (best-effort \u2014 \"\n                + \"verify the compiled sequence on engine-space targets).\");\n        }\n\n        // External clip definitions (Unity .fbx.meta clipAnimations): one output clip per\n        // DEFINITION, sliced out of its take; TakeIndex addresses the definitions then\n        // (see RetargetRequest.ClipDefinitions).\n        if (request.ClipDefinitions is { Count: > 0 } clipDefs)\n        {\n            return ProcessClipDefinitions(\n                request, target, context, options, usedNames, clips, entries,\n                scene, map, report, sourceId, mapsPinky, clipDefs);\n        }\n\n        // TakeIndex narrows the conversion to a single take (UI per-take entries submit one\n        // request per selected take); null keeps the historical convert-all-takes behavior.\n        var takeStart = 0;\n        var takeEnd = scene.Clips.Count;\n        if (request.TakeIndex is { } takeIndex)\n        {\n            if (takeIndex < 0 || takeIndex >= scene.Clips.Count)\n            {\n                clips.Add(new ClipResult\n                {\n                    ClipName = FileStem(request.SourceFileName),\n                    SourceFileName = request.SourceFileName,\n                    SourceId = sourceId,\n                    Mapping = report,\n                    Success = false,\n                    Error = $\"Take index {takeIndex} is out of range: the source file \"\n                        + $\"contains {scene.Clips.Count} take(s).\",\n                });\n                return false;\n            }\n            takeStart = takeIndex;\n            takeEnd = takeIndex + 1;\n        }\n\n        var anyPinkySuccess = false;\n        for (var take = takeStart; take < takeEnd; take++)\n        {\n            var clipName = UniqueClipName(\n                SanitizeClipName(RequestedClipName(request, scene, take)),\n                usedNames, options.AutoSuffixCollisions);\n            anyPinkySuccess |= ConvertOne(\n                request, target, context, options, usedNames, clips, entries,\n                scene, map, report, sourceId, mapsPinky, take, clipName);\n        }\n\n        return anyPinkySuccess;\n    }\n\n    /// <summary>\n    /// The definitions variant of the take loop: each <see cref=\"ExternalClipDef\"/> becomes\n    /// its own clip result \u2014 the definition's take is located by\n    /// <see cref=\"ExternalClipDef.TakeName\"/> (falling back to the file's first take), sliced\n    /// to the definition's native-frame range via <see cref=\"UnityMeta.Slice\"/> and solved as\n    /// a single-clip scene. Returns true when at least one clip converted successfully with a\n    /// pinky-driving mapping.\n    /// </summary>\n    private static bool ProcessClipDefinitions(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        BatchOptions options, HashSet<string> usedNames,\n        List<ClipResult> clips, List<AnimEntry> entries,\n        SourceScene scene, MappingResult map, MappingReportInfo report,\n        string sourceId, bool mapsPinky, IReadOnlyList<ExternalClipDef> clipDefs)\n    {\n        var defStart = 0;\n        var defEnd = clipDefs.Count;\n        if (request.TakeIndex is { } defIndex)\n        {\n            if (defIndex < 0 || defIndex >= clipDefs.Count)\n            {\n                clips.Add(new ClipResult\n                {\n                    ClipName = FileStem(request.SourceFileName),\n                    SourceFileName = request.SourceFileName,\n                    SourceId = sourceId,\n                    Mapping = report,\n                    Success = false,\n                    Error = $\"Clip-definition index {defIndex} is out of range: the request \"\n                        + $\"carries {clipDefs.Count} clip definition(s).\",\n                });\n                return false;\n            }\n            defStart = defIndex;\n            defEnd = defIndex + 1;\n        }\n\n        var anyPinkySuccess = false;\n        for (var d = defStart; d < defEnd; d++)\n        {\n            var def = clipDefs[d];\n            var requestedName = !string.IsNullOrWhiteSpace(def.Name)\n                ? def.Name\n                : clipDefs.Count > 1 ? $\"{FileStem(request.SourceFileName)}_{d + 1}\" : FileStem(request.SourceFileName);\n            var clipName = UniqueClipName(\n                SanitizeClipName(requestedName), usedNames, options.AutoSuffixCollisions);\n\n            var take = TakeForDefinition(scene, def);\n            var sliced = UnityMeta.Slice(scene.Clips[take], def, clipName);\n\n            // Same skeleton/axes, ONE clip: the regular pipeline then solves \"take 0\" of it.\n            var defScene = new SourceScene(\n                scene.Skeleton, new[] { sliced }, scene.UnitScaleCm,\n                scene.UpAxis, scene.UpAxisSign,\n                scene.FrontAxis, scene.FrontAxisSign,\n                scene.CoordAxis, scene.CoordAxisSign,\n                scene.OriginalUpAxis, scene.Notes)\n            {\n                AuthoredMapping = scene.AuthoredMapping,\n                RestPlacementAuthored = scene.RestPlacementAuthored,\n            };\n\n            anyPinkySuccess |= ConvertOne(\n                request, target, context, options, usedNames, clips, entries,\n                defScene, map, report, sourceId, mapsPinky, take: 0, clipName);\n        }\n\n        return anyPinkySuccess;\n    }\n\n    /// <summary>The take a definition's frame range refers to: matched by take name when the\n    /// definition records one (Unity's <c>takeName</c>, e.g. <c>root|Animation</c>), else \u2014\n    /// and when nothing matches \u2014 the file's first take.</summary>\n    private static int TakeForDefinition(SourceScene scene, ExternalClipDef def)\n    {\n        if (!string.IsNullOrWhiteSpace(def.TakeName))\n        {\n            for (var i = 0; i < scene.Clips.Count; i++)\n            {\n                if (string.Equals(scene.Clips[i].Name, def.TakeName, StringComparison.Ordinal))\n                    return i;\n            }\n        }\n        return 0;\n    }\n\n    /// <summary>Solves ONE clip (take <paramref name=\"take\"/> of <paramref name=\"scene\"/>)\n    /// end to end \u2014 solve + cleanup + DMX, plus the optional mirrored twin\n    /// (<see cref=\"RetargetRequest.CreateMirroredVariant\"/>) \u2014 appending success or failure\n    /// <see cref=\"ClipResult\"/>s (failures never abort the batch). Returns true on success\n    /// with a pinky-driving mapping.</summary>\n    private static bool ConvertOne(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        BatchOptions options, HashSet<string> usedNames,\n        List<ClipResult> clips, List<AnimEntry> entries,\n        SourceScene scene, MappingResult map, MappingReportInfo report,\n        string sourceId, bool mapsPinky, int take, string clipName)\n    {\n        Clip clip;\n        try\n        {\n            clip = SolveAndClean(request, target, context, scene, map, report, take, clipName);\n            EmitClip(request, target, context, options, usedNames, clips, entries, report,\n                sourceId, clipName, clip.Frames, clip.Fps, clip.Looping, isMirrored: false);\n        }\n        catch (Exception e)\n        {\n            clips.Add(new ClipResult\n            {\n                ClipName = clipName,\n                SourceFileName = request.SourceFileName,\n                SourceId = sourceId,\n                Mapping = report,\n                Success = false,\n                Error = e.Message,\n            });\n            return false;\n        }\n\n        if (request.CreateMirroredVariant)\n        {\n            // The twin gets its own collision-suffixed name and its own failure isolation:\n            // a mirror problem (asymmetric rig) fails ONLY the twin, never the primary clip.\n            var mirroredName = UniqueClipName(\n                SanitizeClipName(clipName + \"_M\"), usedNames, options.AutoSuffixCollisions);\n            try\n            {\n                // SOURCE-SIDE MIRROR (southpaw G8 mirror fix, gate3_review.md 3.4 and the\n                // G8 bisect evidence): the SOURCE clip is mirrored across the source\n                // character's sagittal plane and the twin then runs through the COMPLETE\n                // unmodified primary pipeline (solver, cleanups, ground alignment, IK\n                // bake, orphan re-anchor). The emitted _M clip is a first-class primary\n                // clip in every representational respect, indistinguishable from a clip\n                // an animator authored mirrored. Target-space channel mirroring, however\n                // geometrically exact, produced data the ENGINE's render-side sequence\n                // evaluation mangles (measured: a mirrored pelvis channel alone renders\n                // the whole model upside down while every CPU-side bone API reports a\n                // perfect upright mirror); no data conjugation convention survived that\n                // stage, so the mirror moved to the source side where no alien data\n                // shape can exist.\n                var mirroredScene = SourceMirror.MirrorTake(scene, map, take);\n                var mirroredClip = SolveAndClean(\n                    request, target, context, mirroredScene, map, report, take, mirroredName);\n                EmitClip(request, target, context, options, usedNames, clips, entries, report,\n                    sourceId, mirroredName, mirroredClip.Frames, mirroredClip.Fps,\n                    clip.Looping, isMirrored: true);\n            }\n            catch (Exception e)\n            {\n                clips.Add(new ClipResult\n                {\n                    ClipName = mirroredName,\n                    SourceFileName = request.SourceFileName,\n                    SourceId = sourceId,\n                    Mapping = report,\n                    Success = false,\n                    Error = $\"mirrored variant: {e.Message}\",\n                });\n            }\n        }\n\n        return mapsPinky;\n    }\n\n    /// <summary>Shared tail of clip production (primary and mirrored twin): optional footstep\n    /// events, DMX serialization, the <see cref=\"ClipResult\"/> and the vmdl\n    /// <see cref=\"AnimEntry\"/> \u2014 plus the additive (<c>_delta</c>) companion entry when\n    /// <see cref=\"RetargetRequest.CreateAdditiveVariant\"/> is on (a second AnimFile REUSING\n    /// the clip's DMX with an AnimSubtract child, shipped-citizen shape; no separate\n    /// <see cref=\"ClipResult\"/> since no separate DMX exists).</summary>\n    private static void EmitClip(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        BatchOptions options, HashSet<string> usedNames,\n        List<ClipResult> clips, List<AnimEntry> entries,\n        MappingReportInfo report, string sourceId,\n        string clipName, List<XForm[]> frames, float fps, bool looping, bool isMirrored)\n    {\n        var events = GenerateFootsteps(request, target, context, report, frames, fps);\n        var dmxFileName = SanitizeFileName(clipName) + \".dmx\";\n        // Embedded-mesh vmdls and compiled Z-up targets compile root channels 90\u00b0 about the declared\n        // up axis away from the mesh bind; child channels are unaffected. Compensate the\n        // serialized copy only so compiled playback matches the solved preview.\n        var dmxFrames = !string.IsNullOrEmpty(target.MeshFilePath) || target.UpAxis == TargetUpAxis.ZUpEngine\n            ? CompensateEmbeddedMeshRootYaw(frames, target.Rig, target.UpAxis)\n            : frames;\n        var dmx = DmxWriter.Write(\n            target.Rig.Skeleton, new Clip(clipName, fps, looping, dmxFrames), new DmxWriteOptions\n            {\n                Name = clipName,\n                SourceNote = isMirrored ? request.SourceFileName + \" (mirrored)\" : request.SourceFileName,\n                // Design \u00a73: ConstraintDriven (twist/helper) bones keep their joints +\n                // bind in the DMX but get NO channels \u2014 the model's AnimConstraintList\n                // drives them. Face bones are exempt from the exclusion (rest-local\n                // channels): nothing drives them in a compiled sequence, and channel-less\n                // face joints bake statically (eyes out of sockets in ModelDoc). Custom\n                // rigs (FromSkeleton) have NO constraint list \u2014 their helpers keep baked\n                // channels or twist bones freeze (candy-wrapped wrists).\n                // MIRRORED clips use the IDENTICAL exclusion set (data-shape parity with\n                // primary clips, southpaw G8 mirror fix): a channel-less constraint-driven\n                // bone on a mirrored-body clip is no different from one on any leftward\n                // primary pose; the model's AnimConstraintList drives it at runtime either\n                // way. (ClipMirror.MirrorSafeExclusions remains available for consumers\n                // that need reflection-exact data for excluded bones.)\n                ChannelExcludedBones = target.Rig.HelpersAreConstraintDriven\n                    ? context.ConstraintDrivenBones\n                    : null,\n                UpAxisY = target.UpAxis == TargetUpAxis.YUpCm,\n            });\n\n        var extractMotion = request.RootMotion == RootMotionMode.Extract;\n\n        // Additive variant: '<clip>_delta' (shipped naming), collision-suffixed like every\n        // other batch name. Only the NAME is produced here \u2014 the vmdl entry below reuses\n        // the base clip's DMX (resourcecompiler does the reference-frame subtraction).\n        var deltaName = request.CreateAdditiveVariant\n            ? UniqueClipName(\n                SanitizeClipName(clipName + \"_delta\"), usedNames, options.AutoSuffixCollisions)\n            : null;\n\n        clips.Add(new ClipResult\n        {\n            ClipName = clipName,\n            SourceFileName = request.SourceFileName,\n            SourceId = sourceId,\n            DmxFileName = dmxFileName,\n            DmxContent = dmx,\n            Mapping = report,\n            Success = true,\n            SolvedFrames = frames,\n            Fps = fps,\n            Looping = looping,\n            ExtractMotion = extractMotion,\n            FootstepEvents = events,\n            IsMirroredVariant = isMirrored,\n            HasAdditiveVariant = deltaName is not null,\n            AdditiveVariantName = deltaName,\n        });\n        var sourceFilename = JoinAssetPath(options.DmxFolderRelative, dmxFileName);\n        entries.Add(new AnimEntry\n        {\n            Name = clipName,\n            SourceFilename = sourceFilename,\n            Looping = looping,\n            ExtractMotion = extractMotion,\n            Events = events,\n        });\n        if (deltaName is not null)\n        {\n            // The shipped _delta sequences carry the AnimSubtract child and nothing else\n            // (no motion extraction, no events) \u2014 an additive layer fires no footsteps and\n            // extracting root motion from a delta makes no sense.\n            entries.Add(new AnimEntry\n            {\n                Name = deltaName,\n                SourceFilename = sourceFilename,\n                Looping = looping,\n                SubtractAnimName = clipName,\n                SubtractFrame = 0,\n            });\n        }\n    }\n\n    /// <summary>\n    /// Generates the <c>AE_FOOTSTEP</c> events for a solved clip when the request asks for\n    /// them (<see cref=\"RetargetRequest.GenerateFootstepEvents\"/>): plant intervals are\n    /// detected on the SOLVED TARGET frames (this is where the engine plays the clip, so\n    /// touchdowns must be measured here), each interval start = one footstep\n    /// (<see cref=\"FootstepEvents\"/>). Empty when the feature is off or the target rig lacks\n    /// the leg chains / character up (noted on the report then).\n    /// </summary>\n    private static IReadOnlyList<AnimEventEntry> GenerateFootsteps(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        MappingReportInfo report, List<XForm[]> frames, float fps)\n    {\n        if (!request.GenerateFootstepEvents)\n            return Array.Empty<AnimEventEntry>();\n        if (context.Up is not { } up || context.FootChains is not { } feet)\n        {\n            AddNote(report, \"Footstep events skipped: \" + context.UpOrChainProblem);\n            return Array.Empty<AnimEventEntry>();\n        }\n        return FootstepEvents.Generate(\n            frames, target.Rig.Skeleton, feet.Left, feet.Right, up, fps,\n            ScaledPlantOptions(target));\n    }\n\n    /// <summary>Default plant thresholds are cm-tuned; engine-space rigs are in inches, so\n    /// they are scaled by the cm\u2192inch factor to keep the same physical sensitivity (shared by\n    /// the foot-plant cleanup and the footstep-event detection).</summary>\n    private static FootPlantOptions ScaledPlantOptions(RetargetTargetSpec target)\n    {\n        var options = new FootPlantOptions();\n        if (target.UpAxis == TargetUpAxis.ZUpEngine)\n        {\n            options.SpeedThresholdCmPerSec *= RetargetTargetSpec.SboxSourceScale;\n            options.HeightThresholdCm *= RetargetTargetSpec.SboxSourceScale;\n        }\n        return options;\n    }\n\n    private static bool MapsPinkyRole(MappingResult map)\n    {\n        foreach (var role in map.RoleToBone.Keys)\n        {\n            if (role.ToString().StartsWith(\"Pinky\", StringComparison.Ordinal))\n                return true;\n        }\n        return false;\n    }\n\n    /// <summary>Solve one take and run the target-space cleanup + IK baking passes.</summary>\n    private static Clip SolveAndClean(\n        RetargetRequest request, RetargetTargetSpec target, TargetContext context,\n        SourceScene scene, MappingResult map, MappingReportInfo report, int take, string clipName)\n    {\n        var requested = request.Solve ?? new SolveOptions();\n        if(request.MocapCorrections is {} wristSettings)\n        {\n            Motion.WristPositionOffsets.Validate(wristSettings.WristOffsets);\n            if(wristSettings.WristOffsets.Any(e=>e.Enabled))\n                throw new NotSupportedException(\"Manual wrist offsets currently require camera-relative hand capture.\");\n        }\n        if(scene.CaptureContacts?.Contacts.Any(c=>c.Review==Motion.ContactReview.Confirmed&&!string.IsNullOrEmpty(c.Object))==true)\n            throw new NotSupportedException(\"Confirmed prop constraints currently require camera-relative hand capture. Disable those constraints to preview body motion; object tracks remain available in captured-skeleton export.\");\n        var captureClavicleDirections = scene.CaptureSpace is not null && requested.TransferModes is null;\n        if (captureClavicleDirections)\n        {\n            // Body-model collar joints are not the target's anatomical rest carriage.\n            // SMPL's zero-pose collar->shoulder slopes upward; its reconstructed neutral\n            // pose rotates that line down to level. Replaying the same delta onto the\n            // Human's already-level collar line lowers its shoulders a second time.\n            AddNote(report, \"Full-body capture transfers observed clavicle directions while retaining target bone lengths and attachment positions.\");\n        }\n        var solved = new GeometricSolver().Solve(scene, map, target.Rig, new SolveOptions\n        {\n            GroundedLegDirections = request.FootPlantCleanup,\n            HipScaleHorizontal = requested.HipScaleHorizontal,\n            HipScaleVertical = requested.HipScaleVertical,\n            TransferFingers = requested.TransferFingers,\n            TransferModes = requested.TransferModes,\n            CaptureClavicleDirections = captureClavicleDirections,\n            NeutralSourceRest = captureClavicleDirections,\n            ClipIndex = take,\n            ClipName = clipName,\n        });\n        var frames = solved.Frames;\n\n        // ---- embedded-take fidelity: authored local translations pass through ----------\n        if (request.PreserveSourceTranslations)\n            PassThroughSourceTranslations(scene, target.Rig, frames, take, report);\n\n        // ---- foot-plant cleanup (target space; up axis from the TARGET character frame) ----\n        if (request.FootPlantCleanup)\n        {\n            if (context.Up is { } up && context.FootChains is { } feet)\n            {\n                // Grounded stance alignment first: levels planted soles against the ground\n                // (removes the stance offset a non-stance source rest leaves in the solver's\n                // rest-relative foot transfer). Plants are detected on the SOURCE clip \u2014\n                // source-space candidates; hip-height rescaling can push the solved target trajectories\n                // outside the cm-tuned Kovar thresholds. Composes with the position pinning\n                // below (this rotates feet about their own joints; the pinning preserves\n                // foot world rotations).\n                // Reconstructed bodies: restore the performer's stance width on differently\n                // proportioned hips before anything is levelled or anchored.\n                if(scene.CaptureSpace is not null)\n                {\n                    var stance=Motion.CaptureStanceProportion.Apply(frames,scene,map,target.Rig,feet.Left,feet.Right);\n                    if(stance.Samples>0)AddNote(report,$\"Stance proportion: each foot moved {stance.HalfWidthCorrection:F2} target units toward the body's centre line, because this target's hip joints are wider relative to its legs than the performer's. Leg lengths and foot orientation are preserved.\");\n                }\n                GroundAlignFeet(frames, scene, map, target.Rig.Skeleton, feet, up, solved.Fps, take);\n\n                var plantOptions=ScaledPlantOptions(target);\n                // Reconstructed contacts can be unreachable on different proportions.\n                // Keep captured target limb lengths fixed instead of stretching to a guess.\n                if(scene.CaptureSpace is not null)plantOptions.MaxStretch=0f;\n                FootPlant.Apply(\n                    frames, target.Rig.Skeleton, feet.Left, feet.Right, up, solved.Fps,\n                    plantOptions);\n\n                // Support ground alignment: one constant vertical offset per clip that\n                // restores the SOURCE-authored foot-to-ground relationship (southpaw\n                // final regeneration package, gate4_review.md 3.1 / DEFERRED.md f2).\n                AlignSupportToGround(frames, scene, map, target.Rig, feet, up, report, take);\n                MatchSourceFootHeights(frames, scene, map, target.Rig, feet, up, take);\n            }\n            else\n            {\n                AddNote(report, \"Foot-plant cleanup skipped: \" + context.UpOrChainProblem);\n            }\n        }\n\n        // A reconstructed body has no finger tracks; give its hands a resting shape, not the bind pose.\n        if(scene.CaptureSpace is not null)\n        {\n            if(Motion.CaptureSpineSpread.Apply(frames,target.Rig)>0)AddNote(report,\"Spine: each frame's bend from the hips to the chest is shared evenly between the spine bones; the network puts most of it in the lowest one. Chest, head and arms are unchanged.\");\n            var shoulders=Motion.CaptureShoulderCarriage.Apply(frames,scene.Clips[take].Frames,scene.Skeleton,map,target.Rig);\n            if(shoulders>0)AddNote(report,$\"Shoulders: {shoulders} clavicle samples carry the performer's change from their own rest shoulder line onto this target's rest shoulder line, instead of copying a differently built clavicle's direction. Arms keep their solved orientation.\");\n            // After the shoulders are placed: restore the performer's hand spacing on differently proportioned shoulders.\n            var arms=Motion.CaptureArmProportion.Apply(frames,scene.Skeleton,map,target.Rig);\n            if(arms.Samples>0)AddNote(report,$\"Hand spacing: wrists in front of or across the body moved up to {arms.HalfWidthCorrection:F2} target units toward the centre line, because this target's shoulders are wider relative to its arms than the performer's. Arm lengths and hand orientation are preserved; outstretched arms are left alone.\");\n            var together=Motion.CaptureHandRelation.Apply(frames,scene.Clips[take].Frames,scene.Skeleton,map,target.Rig);\n            if(together>0)AddNote(report,$\"Hands together: in {together} frames the performer's hands were close (crossing, clapping or touching) and the character's hands were placed the same way from each other, scaled to its arms.\");\n            var relaxed=Motion.RelaxedHands.Apply(frames,map,target.Rig);\n            if(relaxed>0)AddNote(report,$\"Hands: this body capture has no finger tracks, so {relaxed} target finger joints hold one authored, slightly curled resting pose instead of the bind pose. It is not captured finger motion.\");\n        }\n\n        // ---- optional arm effector IK (default off: the solver already matches anatomical\n        // directions; arm IK is only for reach-critical work) ----\n        if (request.ArmEffectorIk)\n        {\n            var problem = ArmIkCleanup.Apply(frames, scene, map, target.Rig, context, take);\n            if (problem is not null)\n                AddNote(report, \"Arm effector IK skipped: \" + problem);\n        }\n\n        // ---- root motion (see class remarks for the Extract \u2194 ExtractMotion mapping) ----\n        if(request.FootPlantCleanup&&(request.MocapCorrections?.StabilizeFeet??true))\n        {\n            var anchored=Motion.CaptureContactRoot.Apply(frames,scene,map,target.Rig,target.UpAxis);\n            if(anchored>0)AddNote(report,FormattableString.Invariant($\"Travel from contacts: planted feet no longer slide; the body's travel was corrected by up to {anchored:F0} cm to match them.\"));\n            var locking=Motion.CaptureFootLock.Apply(frames,scene,map,target.Rig,target.UpAxis);\n            if(locking.ConstrainedSamples>0)AddNote(report,$\"Final target foot anchors: {locking.ConstrainedSamples} leg samples; maximum reach residual {locking.MaximumReachResidual:F4} target units; level-floor height drift of up to {locking.MaximumFloorDrift:F2} target units removed from the root. Backend static probabilities are contact suggestions, not measured ground truth.\");\n            // Keep the whole clip on the floor, including camera-relative captures and dance with few plants.\n            if(scene.CaptureSpace is not null)\n            {\n                var contactMask=Motion.CaptureContactRoot.ContactMask(frames,scene,map,target.Rig,target.UpAxis);\n                var grounded=Motion.CaptureGround.Apply(frames,target.Rig,target.UpAxis,solved.Fps,contactMask);\n                if(grounded>0)AddNote(report,FormattableString.Invariant($\"Floor followed through the clip: up to {grounded:F1} cm of drift toward or away from the floor removed.\"));\n                var hovering=Motion.CaptureHover.Apply(frames,target.Rig,target.UpAxis,solved.Fps,contactMask);\n                if(hovering>0)AddNote(report,$\"Kept on the floor in {hovering} frames: brief hovering above it or sinking into it removed.\");\n                var seatedFrames=Motion.CaptureSeat.Apply(frames,scene,map,target.Rig,target.UpAxis);\n                if(seatedFrames>0)AddNote(report,$\"Seated on the floor in {seatedFrames} frames: hips lowered onto the floor, feet and resting hands held in place.\");\n                var handsHeld=Motion.CaptureHandPlant.Apply(frames,target.Rig,target.UpAxis,solved.Fps,PlantedHands(scene,map,frames.Count),HandSpread(scene,map,take));\n                if(handsHeld>0)AddNote(report,$\"Hands on the floor held in place in {handsHeld} hand samples: palms resting on the floor no longer slide or hover.\");\n            }\n        }\n        // Last of the leg work: no thigh, shin or foot turns far more in one frame than around it.\n        if(scene.CaptureSpace is not null&&Motion.CaptureLegSnaps.Apply(frames,target.Rig,solved.Fps,target.UpAxis==TargetUpAxis.ZUpEngine?39.3700787f:100f,PlantedFeet(scene,map,frames.Count)) is var snaps&&snaps>0)\n            AddNote(report,$\"Leg continuity corrected in {snaps} samples: isolated rotation or knee-position jolts were spread over neighbouring frames, preserving foot anchors where the constraints allowed.\");\n        ApplyRootMotion(request.RootMotion, frames, context, report);\n\n        if (request.MocapCorrections is { } corrections)\n        {\n            Motion.TargetCorrections.Apply(frames, target.Rig, target.UpAxis, corrections);\n            if (corrections.FirstPerson) AddNote(report, \"Shoulders and elbows are generated target-rig IK, not measured joints.\");\n        }\n\n        if (scene.CaptureSpace is not null)\n        {\n            var clearance = Motion.CaptureArmClearance.Apply(frames, scene.Clips[take].Frames, scene.Skeleton, map,\n                target.Rig, solved.Fps, out var unresolvedContacts, out var maximumPenetration);\n            if (clearance.Samples > 0)\n                AddNote(report, FormattableString.Invariant($\"Torso contact: DigitalRune CCD adjusted {clearance.Samples} hand samples by up to {clearance.Largest:F2} target units, preserving wrist attitude and finger articulation. Clearance uses a bone-derived body proxy.\"));\n            if (unresolvedContacts > 0)\n                AddNote(report, FormattableString.Invariant($\"Torso contact remains unresolved in {unresolvedContacts} hand samples (up to {maximumPenetration:F3} target units). Fixed arm lengths and wrist attitude prevented a clear proxy pose; review these contacts.\"));\n        }\n\n        // Last of the pose cleanup: whatever snap a step above left (an IK flip, a contact pushed clear, a hold handed\n        // over) is pulled back onto its neighbours' path, keeping planted hands and feet where they are.\n        if (scene.CaptureSpace is not null && Motion.CaptureDespike.Apply(frames, target.Rig, target.UpAxis == TargetUpAxis.ZUpEngine ? 1 / 2.54f : 1f) is var smoothedSnaps && smoothedSnaps > 0)\n            AddNote(report, $\"Snaps removed after cleanup: {smoothedSnaps} joint samples that left the smooth path through their neighbours were pulled back onto it.\");\n\n        // ---- IK helper bones (root_IK, IK targets, ikrule) need real baked channels ----\n        if (context.HasIkBakedBones)\n            IkBoneBaker.Bake(frames, target.Rig);\n\n        // ---- unmapped limb twist bones follow their joint's roll ------------------------\n        // Mocap exports a portable baked armature, so it cannot rely on the target\n        // model's runtime constraints. Its preview overrides those helpers too.\n        // Keep runtime-owned helpers only for the ordinary model-constraint path.\n        var twistCount = TwistBoneFollow.Apply(frames, target.Rig,\n            request.MocapCorrections is null && target.Rig.HelpersAreConstraintDriven ? context.ConstraintDrivenBones : null);\n        if (twistCount > 0)\n            AddNote(report, $\"{twistCount} limb deform helper bone(s) follow their \"\n                + \"neighboring joints (left at rest they pinch or candy-wrap the skin).\");\n\n        // ---- orphan helper bones ride the hips (LAST: anchored to the FINAL hips, after\n        // foot-plant pinning / root motion have settled the trajectory) -------------------\n        FollowHipsWithOrphanBones(target.Rig, frames, report);\n\n        var looping = request.LoopingOverride ?? solved.Looping;\n        return new Clip(clipName, solved.Fps, looping, frames);\n    }\n\n    /// <summary>Per source frame, how far apart the performer's hands are across the floor, in shoulder widths; null when the\n    /// source lacks hands or shoulders. The capture is Y-up.</summary>\n    static float[] HandSpread(SourceScene scene,MappingResult map,int take)\n    {\n        if(!map.RoleToBone.TryGetValue(BoneRole.HandL,out var handL)||!map.RoleToBone.TryGetValue(BoneRole.HandR,out var handR)\n            ||!map.RoleToBone.TryGetValue(BoneRole.UpperArmL,out var armL)||!map.RoleToBone.TryGetValue(BoneRole.UpperArmR,out var armR))return null;\n        var source=scene.Clips[take].Frames;var world=new XForm[scene.Skeleton.Count];var spread=new float[source.Count];\n        for(var f=0;f<source.Count;f++)\n        {\n            FkUtil.ToWorld(source[f],scene.Skeleton,world);\n            var apart=world[handL].Pos-world[handR].Pos;apart.Y=0;\n            var shoulders=Vector3.Distance(world[armL].Pos,world[armR].Pos);\n            spread[f]=shoulders>1e-6f?apart.Length()/shoulders:0;\n        }\n        return spread;\n    }\n\n    /// <summary>Frames where the capture marks each hand on the floor (stationary probability at least one half).</summary>\n    static Dictionary<BoneRole,bool[]> PlantedHands(SourceScene scene,MappingResult map,int count)\n        =>new[]{BoneRole.HandL,BoneRole.HandR}.ToDictionary(role=>role,role=>\n        {\n            var result=new bool[count];\n            if(map.RoleToBone.TryGetValue(role,out var bone)&&scene.CaptureStationaryJoints?.TryGetValue(scene.Skeleton[bone].Name,out var p)==true&&p.Length==count)\n                for(var f=0;f<count;f++)result[f]=p[f]>=.5f;\n            return result;\n        });\n\n    /// <summary>Frames where the capture marks each joint planted (stationary probability at least one half): left ankle, left\n    /// toe, right ankle, right toe.</summary>\n    static bool[][] PlantedFeet(SourceScene scene,MappingResult map,int count)\n        =>new[]{BoneRole.FootL,BoneRole.ToeL,BoneRole.FootR,BoneRole.ToeR}.Select(role=>\n        {\n            var result=new bool[count];\n            if(map.RoleToBone.TryGetValue(role,out var bone)&&scene.CaptureStationaryJoints?.TryGetValue(scene.Skeleton[bone].Name,out var p)==true&&p.Length==count)\n                for(var f=0;f<count;f++)result[f]=p[f]>=.5f;\n            return result;\n        }).ToArray();\n\n    /// <summary>\n    /// Unmapped bone subtrees OUTSIDE the mapped skeleton (no mapped ancestor \u2014 cloth and\n    /// physics helpers parented to the scene root; real case: a skirt of 48 kilt bones on\n    /// a Sketchfab catgirl, siblings of the body root) ride the character rigidly. Left\n    /// at their rest locals they freeze at the bind spot while the body animates away\n    /// (\"one part of the body doesn't move at all\") and the mesh skinned across the\n    /// boundary shears (\"completely stretched\"). Each subtree's topmost bone anchors to\n    /// the HIPS \u2014 or to an extremity (hand/foot/head) when its rest sits clearly closer\n    /// to it (a sword resting in the hand follows the hand, not the pelvis). Descendants\n    /// ride along on their rest locals; bones on the hips' own ancestor path stay\n    /// solver-owned (trajectory). A mapped body branch on a separate control tree is\n    /// similarly anchored to the nearest hips-connected mapped joint; its solved rotation\n    /// remains unchanged.\n    /// </summary>\n    private static void FollowHipsWithOrphanBones(\n        TargetRig rig, List<XForm[]> frames, MappingReportInfo report)\n    {\n        var skeleton = rig.Skeleton;\n        if (rig.BoneForRole(BoneRole.Hips) is not { } hips || frames.Count == 0)\n            return;\n\n        var hipsPath = new HashSet<int>();\n        for (var b = hips; b >= 0; b = skeleton[b].ParentIndex)\n            hipsPath.Add(b);\n\n        bool HasMappedAncestor(int bone)\n        {\n            for (var b = skeleton[bone].ParentIndex; b >= 0; b = skeleton[b].ParentIndex)\n            {\n                if (rig.RoleOf(b) is not null)\n                    return true;\n            }\n            return false;\n        }\n\n        var rest = skeleton.RestWorld;\n\n        bool DescendsFrom(int bone, int ancestor)\n        {\n            for (var b = bone; b >= 0; b = skeleton[b].ParentIndex)\n                if (b == ancestor)\n                    return true;\n            return false;\n        }\n\n        // Extremity anchors: adopted only when the orphan rests at less than half its\n        // hips distance \u2014 near-torso helpers (skirts, tails, capes) stay on the hips,\n        // which never mistakes a skirt panel brushing a thigh for hand luggage.\n        var extremities = new List<int>();\n        foreach (var role in new[]\n        {\n            BoneRole.HandL, BoneRole.HandR, BoneRole.FootL, BoneRole.FootR, BoneRole.Head,\n        })\n        {\n            if (rig.BoneForRole(role) is { } bone)\n                extremities.Add(bone);\n        }\n\n        // Topmost orphans: unmapped, off the hips' ancestor path, no mapped ancestor,\n        // and the parent is either the scene root path or absent (children of deeper\n        // orphans ride along unchanged).\n        var tops = new List<(int Bone, int Anchor)>();\n        for (var i = 0; i < skeleton.Count; i++)\n        {\n            if (rig.RoleOf(i) is not null || hipsPath.Contains(i) || HasMappedAncestor(i))\n                continue;\n            var parent = skeleton[i].ParentIndex;\n            if (parent >= 0 && !hipsPath.Contains(parent))\n                continue;\n\n            var anchor = hips;\n            var hipsDistance = (rest[i].Pos - rest[hips].Pos).Length();\n            var best = hipsDistance * 0.5f;\n            foreach (var candidate in extremities)\n            {\n                var distance = (rest[i].Pos - rest[candidate].Pos).Length();\n                if (distance < best)\n                {\n                    best = distance;\n                    anchor = candidate;\n                }\n            }\n            tops.Add((i, anchor));\n        }\n\n        // A few constraint-oriented exports place a real mapped body branch on a parallel\n        // control hierarchy. The common case is a skinned head under CONTROL_NECK while\n        // the deform cervical chain is under the hips. glTF/FBX does not preserve the DCC\n        // constraint that joined those trees, so rotations solve but the branch stays at\n        // its bind position. Anchor each topmost detached mapped branch to the nearest\n        // mapped joint that really descends from the hips, preserving its solved rotation.\n        var connectedMapped = Enumerable.Range(0, skeleton.Count)\n            .Where(i => rig.RoleOf(i) is not null && DescendsFrom(i, hips))\n            .ToList();\n        var detachedMapped = new List<(int Bone, int Anchor)>();\n        for (var i = 0; i < skeleton.Count; i++)\n        {\n            if (rig.RoleOf(i) is null || hipsPath.Contains(i) || DescendsFrom(i, hips)\n                || HasMappedAncestor(i) || connectedMapped.Count == 0)\n                continue;\n            var anchor = connectedMapped\n                .OrderBy(candidate => (rest[i].Pos - rest[candidate].Pos).LengthSquared())\n                .First();\n            detachedMapped.Add((i, anchor));\n        }\n\n        // A detached deform head may retain a small control-space bind pitch after the DCC\n        // constraint is lost. Infer its gaze only when one local axis already agrees closely\n        // with character-forward, then remove the small vertical component. Applying the\n        // correction in rest-local space preserves every solved animation delta.\n        var neutralHead = -1;\n        var neutralHeadCorrection = Quaternion.Identity;\n        foreach (var (bone, _) in detachedMapped)\n        {\n            if (rig.RoleOf(bone) == BoneRole.Head\n                && TryDetachedHeadNeutralCorrection(rig, bone, out neutralHeadCorrection))\n            {\n                neutralHead = bone;\n                break;\n            }\n        }\n\n        if (tops.Count == 0 && detachedMapped.Count == 0)\n            return;\n\n        var anchorRestInverse = new Dictionary<int, XForm>();\n        foreach (var (_, anchor) in tops)\n            anchorRestInverse[anchor] = rest[anchor].Inverse();\n        foreach (var (_, anchor) in detachedMapped)\n            anchorRestInverse[anchor] = rest[anchor].Inverse();\n\n        foreach (var frame in frames)\n        {\n            var world = new Skeleton.Pose(frame).ToWorld(skeleton);\n            foreach (var (top, anchor) in tops)\n            {\n                var delta = XForm.Compose(world[anchor], anchorRestInverse[anchor]);\n                var parent = skeleton[top].ParentIndex;\n                var parentWorld = parent >= 0 ? world[parent] : XForm.Identity;\n                frame[top] = XForm.ToLocal(\n                    parentWorld, XForm.Compose(delta, rest[top]));\n            }\n\n            if (detachedMapped.Count == 0)\n                continue;\n\n            // Re-evaluate after moving orphan control roots (the detached branch's actual\n            // parent may be inside one). Only position is anchored: its mapped rotation is\n            // the solver's result and must remain authoritative.\n            world = new Skeleton.Pose(frame).ToWorld(skeleton);\n            foreach (var (bone, anchor) in detachedMapped)\n            {\n                var delta = XForm.Compose(world[anchor], anchorRestInverse[anchor]);\n                var rotation = bone == neutralHead\n                    ? MathQ.Normalize(world[bone].Rot * neutralHeadCorrection)\n                    : world[bone].Rot;\n                var desired = new XForm(\n                    XForm.Compose(delta, rest[bone]).Pos,\n                    rotation);\n                var parent = skeleton[bone].ParentIndex;\n                frame[bone] = parent < 0\n                    ? desired\n                    : XForm.ToLocal(world[parent], desired);\n            }\n        }\n        if (tops.Count > 0)\n            AddNote(report,\n                $\"{tops.Count} helper bone subtree(s) outside the mapped skeleton ride the \"\n                + \"character (cloth/physics/prop bones would otherwise freeze at their bind position).\");\n        if (detachedMapped.Count > 0)\n            AddNote(report,\n                $\"{detachedMapped.Count} mapped body branch(es) on separate control hierarchies \"\n                + \"follow the connected skeleton (exported DCC constraints are not available at runtime).\");\n        if (neutralHead >= 0)\n            AddNote(report,\n                \"Detached head bind pitch was leveled to the character facing plane while preserving animation.\");\n    }\n\n    private static void MatchSourceFootHeights(\n        List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,\n        (FootChain Left, FootChain Right) feet, Vector3 up, int take)\n    {\n        if (frames.Count == 0 || !map.RoleToBone.TryGetValue(BoneRole.Hips, out var srcHips)\n            || rig.BoneForRole(BoneRole.Hips) is not int tgtHips)\n            return;\n        var source = scene.Skeleton;\n        var target = rig.Skeleton;\n        if (!scene.RestPlacementAuthored && !RestNormalizer.IsAnatomicalRest(source, map, source.RestWorld))\n            return; // Bone-length-only rests cannot calibrate an anatomical support height.\n        var srcFrames = scene.Clips[take].Frames;\n        if (srcFrames.Count != frames.Count)\n            return;\n        var srcUp = scene.UpAxis switch\n        {\n            0 => new Vector3(scene.UpAxisSign, 0, 0),\n            2 => new Vector3(0, 0, scene.UpAxisSign),\n            _ => new Vector3(0, scene.UpAxisSign, 0),\n        };\n        up = GroundUp(up);\n        var worlds = new XForm[frames.Count][];\n        var restGround = float.PositiveInfinity;\n        var motionGround = float.PositiveInfinity;\n        foreach (var rest in source.RestWorld)\n            restGround = MathF.Min(restGround, Vector3.Dot(rest.Pos, srcUp));\n        for (var f = 0; f < frames.Count; f++)\n        {\n            worlds[f] = new Skeleton.Pose(srcFrames[f]).ToWorld(source);\n            foreach (var bone in worlds[f])\n                motionGround = MathF.Min(motionGround, Vector3.Dot(bone.Pos, srcUp));\n        }\n        var placement = scene.RestPlacementAuthored ? 0f : motionGround - restGround;\n        var corrections = new List<(FootChain Chain, Vector3[] Goals)>();\n        var lowerPelvis = new float[frames.Count];\n        foreach (var (footRole, toeRole, chain) in new[]\n        {\n            (BoneRole.FootL, BoneRole.ToeL, feet.Left), (BoneRole.FootR, BoneRole.ToeR, feet.Right),\n        })\n        {\n            if (!map.RoleToBone.TryGetValue(footRole, out var foot)\n                || !map.RoleToBone.TryGetValue(toeRole, out var toe) || chain.Toe is not int tgtToe)\n                continue;\n            float Support(IReadOnlyList<XForm> pose, int ankle, int tip, Vector3 vertical)\n                => MathF.Min(Vector3.Dot(pose[ankle].Pos, vertical), Vector3.Dot(pose[tip].Pos, vertical));\n            var srcRest = Support(source.RestWorld, foot, toe, srcUp);\n            var tgtRest = Support(target.RestWorld, chain.Ankle, tgtToe, up);\n            // Animation-only FBXs can store a mid-stride rest, with one foot lifted.\n            // That raised foot is not a ground reference: subtracting it drives its\n            // planted frames below the floor. An authored rest never needs a higher\n            // support baseline than the lowest support actually reached by that foot.\n            if (scene.RestPlacementAuthored)\n                foreach (var pose in worlds)\n                    srcRest = MathF.Min(srcRest, Support(pose, foot, toe, srcUp));\n            var srcHeight = Vector3.Dot(source.RestWorld[srcHips].Pos, srcUp) - srcRest;\n            if (srcHeight <= .001f)\n                continue;\n            var ratio = Math.Clamp((Vector3.Dot(target.RestWorld[tgtHips].Pos, up) - tgtRest) / srcHeight, .25f, 4f);\n            var goals = new Vector3[frames.Count];\n            for (var f = 0; f < frames.Count; f++)\n            {\n                var world = new Skeleton.Pose(frames[f]).ToWorld(target);\n                var desired = tgtRest + (Support(worlds[f], foot, toe, srcUp) - srcRest - placement) * ratio;\n                goals[f] = world[chain.Ankle].Pos + up * (desired - Support(world, chain.Ankle, tgtToe, up));\n                var reach = Vector3.Distance(world[chain.Hip].Pos, world[chain.Knee].Pos)\n                    + Vector3.Distance(world[chain.Knee].Pos, world[chain.Ankle].Pos);\n                var toHip = world[chain.Hip].Pos - goals[f];\n                if (scene.CaptureSpace is not null)\n                {\n                    lowerPelvis[f] = MathF.Max(lowerPelvis[f], Motion.CaptureLegReach.Lowering(toHip, up, reach));\n                    continue;\n                }\n                var vertical = Vector3.Dot(toHip, up);\n                var horizontal = toHip - up * vertical;\n                if (horizontal.LengthSquared() < reach * reach)\n                    lowerPelvis[f] = MathF.Max(lowerPelvis[f], vertical\n                        - MathF.Sqrt(reach * reach - horizontal.LengthSquared()));\n            }\n            corrections.Add((chain, goals));\n        }\n        // At full extension, lower the pelvis only as far as needed to reach BOTH\n        // contacts. Stretching bones or accepting an unreachable goal leaves a hover.\n        for (var f = 0; f < frames.Count; f++)\n        {\n            if (lowerPelvis[f] <= 0f) continue;\n            var parent = target[tgtHips].ParentIndex;\n            var shift = -up * lowerPelvis[f];\n            if (parent >= 0)\n                shift = Vector3.Transform(shift, Quaternion.Conjugate(\n                    new Skeleton.Pose(frames[f]).ToWorld(target)[parent].Rot));\n            frames[f][tgtHips].Pos += shift;\n        }\n        foreach (var (chain, goals) in corrections)\n        {\n            // Vertical IK preserves horizontal travel and foot rotation; it never scales bones.\n            EffectorIk.ApplyGoals(frames, target,\n                new LimbChain { Upper = chain.Hip, Lower = chain.Knee, End = chain.Ankle },\n                goals, ArmIkCleanup.RestBendAxis(target, chain.Hip, chain.Knee, chain.Ankle), soften: 0f);\n        }\n    }\n\n    private static bool TryDetachedHeadNeutralCorrection(\n        TargetRig rig, int head, out Quaternion localCorrection)\n    {\n        localCorrection = Quaternion.Identity;\n        CharacterFrame frame;\n        try\n        {\n            frame = CharacterFrame.Compute(\n                rig.Skeleton, rig.ToMappingResult(), rig.Skeleton.RestWorld);\n        }\n        catch (ArgumentException)\n        {\n            return false;\n        }\n\n        var restRotation = MathQ.Normalize(rig.Skeleton.RestWorld[head].Rot);\n        var gaze = Vector3.Zero;\n        var agreement = float.NegativeInfinity;\n        foreach (var localAxis in new[] { Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ })\n        {\n            var axis = Vector3.Transform(localAxis, restRotation);\n            var dot = Vector3.Dot(axis, frame.Forward);\n            if (MathF.Abs(dot) <= agreement)\n                continue;\n            agreement = MathF.Abs(dot);\n            gaze = dot < 0f ? -axis : axis;\n        }\n\n        var vertical = Vector3.Dot(gaze, frame.Up);\n        const float minAgreement = 0.94f; // local axis must be within 20\u00b0 of facing\n        const float minPitch = 0.5f * MathF.PI / 180f;\n        const float maxPitch = 12f * MathF.PI / 180f;\n        var pitch = MathF.Asin(Math.Clamp(vertical, -1f, 1f));\n        if (agreement < minAgreement || MathF.Abs(pitch) < minPitch || MathF.Abs(pitch) > maxPitch)\n            return false;\n\n        var levelGaze = gaze - frame.Up * vertical;\n        if (levelGaze.LengthSquared() < 1e-8f)\n            return false;\n        levelGaze = Vector3.Normalize(levelGaze);\n\n        var worldCorrection = MathQ.FromTo(gaze, levelGaze);\n        localCorrection = MathQ.Normalize(\n            Quaternion.Conjugate(restRotation) * worldCorrection * restRotation);\n        return true;\n    }\n\n    /// <summary>\n    /// The engine-side yaw correction for embedded meshes and compiled Z-up targets (see\n    /// <see cref=\"EmitClip\"/>): the compiler's source-axis conversion for ROOT-LEVEL\n    /// animation channels lands 90\u00b0 about up away from where it puts the mesh bind.\n    /// Pre-rotating root locals by the inverse importer yaw (\u221290\u00b0 for Y-up,\n    /// +90\u00b0 for Z-up) makes compiled playback match the bind; children are parent-relative.\n    /// </summary>\n    private static List<XForm[]> CompensateEmbeddedMeshRootYaw(\n        IReadOnlyList<XForm[]> frames, TargetRig rig, TargetUpAxis upAxis)\n    {\n        var yUp = upAxis == TargetUpAxis.YUpCm;\n        var axis = yUp ? Vector3.UnitY : Vector3.UnitZ;\n        var yaw = Quaternion.CreateFromAxisAngle(axis, (yUp ? -1f : 1f) * MathF.PI * 0.5f);\n        var skeleton = rig.Skeleton;\n        var result = new List<XForm[]>(frames.Count);\n        foreach (var frame in frames)\n        {\n            var copy = new XForm[frame.Length];\n            for (var i = 0; i < frame.Length; i++)\n            {\n                copy[i] = i < skeleton.Count && skeleton[i].ParentIndex < 0\n                    ? new XForm(\n                        Vector3.Transform(frame[i].Pos, yaw),\n                        MathQ.Normalize(yaw * frame[i].Rot))\n                    : frame[i];\n            }\n            result.Add(copy);\n        }\n        return result;\n    }\n\n    /// <summary>Test seam for <see cref=\"CompensateEmbeddedMeshRootYaw\"/> (gate bisects\n    /// re-serialize mutated frames with the same compensation the pipeline applies).</summary>\n    public static List<XForm[]> TestHook_CompensateEmbeddedMeshRootYaw(\n        IReadOnlyList<XForm[]> frames, RetargetTargetSpec target)\n        => !string.IsNullOrEmpty(target.MeshFilePath) || target.UpAxis == TargetUpAxis.ZUpEngine\n            ? CompensateEmbeddedMeshRootYaw(frames, target.Rig, target.UpAxis)\n            : frames.ToList();\n\n    /// <summary>Test seam for <see cref=\"FollowHipsWithOrphanBones\"/>.</summary>\n    public static void TestHook_FollowOrphans(TargetRig rig, List<XForm[]> frames)\n        => FollowHipsWithOrphanBones(rig, frames, new MappingReportInfo\n        {\n            ProfileName = \"test\",\n            Source = MappingSource.Manual,\n            Confidence = 1f,\n            NeedsUserDecision = false,\n            MappedRoleCount = 0,\n            SkeletonSignature = \"\",\n        });\n\n    /// <summary>\n    /// <see cref=\"RetargetRequest.PreserveSourceTranslations\"/>: per-frame source local\n    /// translations onto same-named target bones. Names are compared engine-sanitized\n    /// (non-alphanumerics \u2192 <c>_</c>: the compiled-model rig the editor rebuilds carries\n    /// <c>Bip01_R_Hand</c> for the file's <c>Bip01 R Hand</c>). A matched bone whose REST\n    /// translation disagrees between the rigs is skipped \u2014 the name collision is then\n    /// coincidence, not the same joint. The hips and its ancestors always stay\n    /// solver-owned (trajectory, root-motion modes, hip rescale).\n    /// </summary>\n    private static void PassThroughSourceTranslations(\n        SourceScene scene, TargetRig rig, List<XForm[]> frames, int take,\n        MappingReportInfo report)\n    {\n        var src = scene.Skeleton;\n        var tgt = rig.Skeleton;\n        var srcClip = scene.Clips[take];\n        if (srcClip.Frames.Count != frames.Count)\n        {\n            AddNote(report, \"Source translations not preserved: frame counts differ \"\n                + $\"({srcClip.Frames.Count} source vs {frames.Count} solved).\");\n            return;\n        }\n\n        static string Key(string name)\n        {\n            Span<char> c = stackalloc char[name.Length];\n            for (var i = 0; i < name.Length; i++)\n                c[i] = char.IsLetterOrDigit(name[i]) ? char.ToLowerInvariant(name[i]) : '_';\n            return new string(c);\n        }\n\n        var srcByName = new Dictionary<string, int>();\n        for (var i = 0; i < src.Count; i++)\n        {\n            // Duplicate keys are ambiguous - poison them rather than guess.\n            var key = Key(src[i].Name);\n            srcByName[key] = srcByName.ContainsKey(key) ? -1 : i;\n        }\n\n        var excluded = new HashSet<int>();\n        if (rig.BoneForRole(BoneRole.Hips) is { } hips)\n            for (var b = hips; b >= 0; b = tgt[b].ParentIndex)\n                excluded.Add(b);\n\n        var applied = 0;\n        for (var t = 0; t < tgt.Count; t++)\n        {\n            if (excluded.Contains(t)\n                || !srcByName.TryGetValue(Key(tgt[t].Name), out var s) || s < 0)\n                continue;\n            // Same joint check: rest translations must agree (same rig, same space).\n            var restDelta = (src[s].RestLocal.Pos - tgt[t].RestLocal.Pos).Length();\n            if (restDelta > MathF.Max(1f, 0.1f * tgt[t].RestLocal.Pos.Length()))\n                continue;\n            for (var f = 0; f < frames.Count; f++)\n                frames[f][t] = new XForm(srcClip.Frames[f][s].Pos, frames[f][t].Rot);\n            applied++;\n        }\n        if (applied > 0)\n            AddNote(report, $\"Embedded take: authored local translations preserved on {applied} bones.\");\n    }\n\n    /// <summary>\n    /// Normalized-rest foot pitch beyond which (toe approaching/above ankle level) the rest\n    /// cannot be a flat stance \u2014 measured stance rests sit at \u221211\u00b0\u2026\u221251\u00b0; the repro artifact\n    /// rig measured +2.7\u00b0 on one foot.\n    /// </summary>\n    private const float StancePitchMaxDeg = -5f;\n\n    /// <summary>Left/right normalized-rest foot pitch asymmetry beyond which the rest is not\n    /// a (symmetric) stance \u2014 measured stance rests differ \u2264 2.4\u00b0; the repro artifact rig\n    /// 13.8\u00b0.</summary>\n    private const float StancePitchAsymmetryDeg = 6f;\n\n    /// <summary>\n    /// The grounded-foot stance recalibration step (<see cref=\"FootGroundAlign\"/>). Runs ONLY\n    /// when the source's NORMALIZED rest \u2014 the solver's delta reference \u2014 is implausible as a\n    /// flat stance (a foot's toe at/above ankle level, or the two feet resting asymmetrically;\n    /// both measured on the repro rig, where T-pose normalization of a bent-leg rest swings\n    /// the feet 14\u201326\u00b0 away from the rig's true stance). On plausible stance rests the solver's\n    /// rest-relative foot transfer is already faithful, and planted-sole deviations are\n    /// genuine articulation (boxing stances, heel rolls) that must NOT be flattened. Plant\n    /// intervals are detected on the SOURCE clip (cm space, default Kovar thresholds).\n    /// Best-effort \u2014 silently skipped when the source maps no complete leg chains + toes or a\n    /// character frame is not computable (the foot transfer is then simply left as solved).\n    /// </summary>\n    private static void GroundAlignFeet(\n        List<XForm[]> frames, SourceScene scene, MappingResult map, SkeletonModel targetSkeleton,\n        (FootChain Left, FootChain Right) targetFeet, Vector3 targetUp, float fps, int take)\n    {\n        FootChain? SourceChain(BoneRole upper, BoneRole lower, BoneRole foot, BoneRole toe)\n            => map.RoleToBone.TryGetValue(upper, out var hip)\n               && map.RoleToBone.TryGetValue(lower, out var knee)\n               && map.RoleToBone.TryGetValue(foot, out var ankle)\n                ? new FootChain\n                {\n                    Hip = hip,\n                    Knee = knee,\n                    Ankle = ankle,\n                    Toe = map.RoleToBone.TryGetValue(toe, out var t) ? t : null,\n                }\n                : null;\n\n        var srcLeft = SourceChain(BoneRole.UpperLegL, BoneRole.LowerLegL, BoneRole.FootL, BoneRole.ToeL);\n        var srcRight = SourceChain(BoneRole.UpperLegR, BoneRole.LowerLegR, BoneRole.FootR, BoneRole.ToeR);\n        if (srcLeft?.Toe is not int srcToeL || srcRight?.Toe is not int srcToeR)\n            return; // toe-less sources take the solver's virtual-foot fallback instead\n\n        // ---- rest-stance plausibility (normalized rest, the solver's delta reference) ----\n        float pitchL, pitchR;\n        Vector3 srcUp;\n        try\n        {\n            var (srcNorm, _) = RestNormalizer.Normalize(scene.Skeleton, map);\n            var srcCanon = CanonicalFrames.Build(scene.Skeleton, map, srcNorm.WorldRest);\n            srcUp = Vector3.Normalize(srcCanon.CharacterUp);\n\n            float RestPitchDeg(int foot, int toe)\n            {\n                var dir = srcNorm.WorldRest[toe].Pos - srcNorm.WorldRest[foot].Pos;\n                if (dir.LengthSquared() < 1e-8f)\n                    return 0f;\n                var s = Vector3.Dot(Vector3.Normalize(dir), srcUp);\n                return MathF.Asin(Math.Clamp(s, -1f, 1f)) * (180f / MathF.PI);\n            }\n\n            pitchL = RestPitchDeg(srcLeft.Ankle, srcToeL);\n            pitchR = RestPitchDeg(srcRight.Ankle, srcToeR);\n        }\n        catch (ArgumentException)\n        {\n            return;\n        }\n\n        var restIsStance = pitchL < StancePitchMaxDeg && pitchR < StancePitchMaxDeg\n            && MathF.Abs(pitchL - pitchR) <= StancePitchAsymmetryDeg;\n        if (restIsStance)\n            return;\n\n        var srcFrames = scene.Clips[take].Frames;\n        var (plantsL, plantsR) = FootPlant.DetectPlantIntervals(\n            srcFrames, scene.Skeleton, srcLeft, srcRight, srcUp, fps);\n        if (plantsL.Count == 0 && plantsR.Count == 0)\n            return;\n\n        FootGroundAlign.Apply(\n            frames, targetSkeleton, targetFeet.Left, targetFeet.Right, targetUp,\n            plantsL, plantsR);\n    }\n\n    /// <summary>\n    /// Restores the clip's SOURCE-authored foot-to-ground relationship with ONE constant\n    /// vertical offset per clip (southpaw final regeneration package: DEFERRED.md f2 and\n    /// gate4_review.md 3.1). The solver's vertical reference is the source REST pelvis;\n    /// mid-pose exports whose kept node rest erased the authored crouch leave every solved\n    /// frame hovering by exactly the erased crouch depth (measured: stance +5.9 cm, steps\n    /// +7.8 to +10.3, slips ~+9, while the source FBX is grounded everywhere). Fix, the\n    /// generalization of the BVH ClipPlacementOffset vertical logic to every source: measure\n    /// the clip's minimum foot support (ankles + toes) in the SOLVED target frames and shift\n    /// the whole clip vertically so that support equals the TARGET rest support plus the\n    /// source clip's own authored support delta (source clip support minus source rest\n    /// support, hip-height scaled). One constant per clip preserves every within-clip lift,\n    /// heel raise and step cycle exactly: authored articulation is never flattened and an\n    /// authored jump stays airborne (its source support delta rides along).\n    /// </summary>\n    private static void AlignSupportToGround(\n        List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,\n        (FootChain Left, FootChain Right) feet, Vector3 up, MappingReportInfo report, int take)\n    {\n        if (frames.Count == 0)\n            return;\n        var skeleton = rig.Skeleton;\n        var rest = skeleton.RestWorld;\n        var srcClip = scene.Clips[take];\n        var src = scene.Skeleton;\n\n        // The GROUND normal is the rig-space vertical axis, not the character-lean up:\n        // the character frame's up tilts a few degrees with the rest posture, and a\n        // tilted dot-metric slants the ground line across a traveling clip (measured:\n        // 28 cm of false offset on a long corpus walk). Snap to the dominant axis.\n        up = GroundUp(up);\n\n        // ---- support-bone set: the roles mapped on BOTH rigs (metrics must compare\n        // the same anatomical points or anthropometric offsets leak into the gap) ----\n        var supportRoles = new List<BoneRole>();\n        foreach (var role in new[] { BoneRole.FootL, BoneRole.FootR, BoneRole.ToeL, BoneRole.ToeR })\n        {\n            if (map.RoleToBone.ContainsKey(role) && rig.BoneForRole(role) is not null)\n                supportRoles.Add(role);\n        }\n        var sourceMeasured = supportRoles.Contains(BoneRole.FootL) && supportRoles.Contains(BoneRole.FootR)\n            && srcClip.Frames.Count > 0 && srcClip.Frames[0].Length == src.Count;\n        if (!sourceMeasured)\n        {\n            // No reliable common support metric: fall back to the ankles the target\n            // chains provide and a zero source gap (best guess: grounded).\n            supportRoles.Clear();\n        }\n\n        var tgtSupportBones = new List<int>();\n        foreach (var role in supportRoles)\n            tgtSupportBones.Add(rig.BoneForRole(role)!.Value);\n        if (tgtSupportBones.Count == 0)\n        {\n            tgtSupportBones.Add(feet.Left.Ankle);\n            tgtSupportBones.Add(feet.Right.Ankle);\n        }\n\n        var tgtRestSupport = float.MaxValue;\n        foreach (var b in tgtSupportBones)\n            tgtRestSupport = MathF.Min(tgtRestSupport, Vector3.Dot(rest[b].Pos, up));\n\n        var solvedSupport = float.MaxValue;\n        foreach (var frame in frames)\n        {\n            var world = new Skeleton.Pose(frame).ToWorld(skeleton);\n            foreach (var b in tgtSupportBones)\n                solvedSupport = MathF.Min(solvedSupport, Vector3.Dot(world[b].Pos, up));\n        }\n\n        // ---- source-authored support gap --------------------------------------\n        float sourceRel = 0f;\n        if (sourceMeasured)\n        {\n            var srcSupportBones = new List<int>();\n            foreach (var role in supportRoles)\n                srcSupportBones.Add(map.RoleToBone[role]);\n\n            var srcUp = scene.UpAxis switch\n            {\n                0 => new Vector3(scene.UpAxisSign, 0f, 0f),\n                2 => new Vector3(0f, 0f, scene.UpAxisSign),\n                _ => new Vector3(0f, scene.UpAxisSign, 0f),\n            };\n            var srcHips = map.RoleToBone.TryGetValue(BoneRole.Hips, out var sh) ? sh : -1;\n\n            var srcRestSupport = float.MaxValue;\n            var srcRestGround = float.MaxValue;\n            for (var b = 0; b < src.Count; b++)\n            {\n                var h = Vector3.Dot(src.RestWorld[b].Pos, srcUp);\n                srcRestGround = MathF.Min(srcRestGround, h);\n            }\n            foreach (var b in srcSupportBones)\n                srcRestSupport = MathF.Min(srcRestSupport, Vector3.Dot(src.RestWorld[b].Pos, srcUp));\n\n            var srcClipSupport = float.MaxValue;\n            var srcMotionGround = float.MaxValue;\n            foreach (var frame in srcClip.Frames)\n            {\n                var world = new Skeleton.Pose(frame).ToWorld(src);\n                foreach (var b in srcSupportBones)\n                    srcClipSupport = MathF.Min(srcClipSupport, Vector3.Dot(world[b].Pos, srcUp));\n                if (!scene.RestPlacementAuthored)\n                {\n                    for (var b = 0; b < src.Count; b++)\n                        srcMotionGround = MathF.Min(srcMotionGround, Vector3.Dot(world[b].Pos, srcUp));\n                }\n            }\n\n            // AUTHORED placements (FBX): the rest stands on the authored ground, so the\n            // gap is simply clip support minus rest support (same bones, same space).\n            // UN-PLACED sources (BVH capture volumes): absolute placement is meaningless,\n            // so both terms go placement-free: the clip's support above its OWN motion\n            // ground (lowest joint anywhere, incl. static origin markers) compared to the\n            // rest pose's support above ITS lowest joint. A grounded walk reads ~0, a\n            // jump reads its true airborne height, a crawl reads its raised feet.\n            float gap;\n            if (scene.RestPlacementAuthored)\n                gap = srcClipSupport - srcRestSupport;\n            else\n                gap = (srcClipSupport - srcMotionGround) - (srcRestSupport - srcRestGround);\n\n            // Hip-height ratio scales the (small) source gap into target units,\n            // clamped against degenerate rest measurements.\n            var ratio = 1f;\n            if (srcHips >= 0 && rig.BoneForRole(BoneRole.Hips) is { } tgtHips)\n            {\n                var srcHipHeight = Vector3.Dot(src.RestWorld[srcHips].Pos, srcUp) - srcRestSupport;\n                var tgtHipHeight = Vector3.Dot(rest[tgtHips].Pos, up) - tgtRestSupport;\n                if (srcHipHeight > 1e-3f && float.IsFinite(tgtHipHeight / srcHipHeight))\n                    ratio = Math.Clamp(tgtHipHeight / srcHipHeight, 0.25f, 4f);\n            }\n            sourceRel = gap * ratio;\n        }\n\n        var delta = tgtRestSupport + sourceRel - solvedSupport;\n        if (!float.IsFinite(delta) || MathF.Abs(delta) > 100f)\n        {\n            AddNote(report, $\"Support ground alignment skipped: implausible offset {delta:0.0}.\");\n            return;\n        }\n        if (MathF.Abs(delta) < 0.01f)\n            return; // already aligned\n\n        var shift = up * delta;\n        foreach (var frame in frames)\n        {\n            for (var i = 0; i < skeleton.Count; i++)\n            {\n                if (skeleton[i].ParentIndex < 0)\n                    frame[i] = new XForm(frame[i].Pos + shift, frame[i].Rot);\n            }\n        }\n        AddNote(report, sourceMeasured\n            ? $\"Support ground alignment: {delta:0.00} vertical offset applied \"\n              + $\"(source-authored support delta {sourceRel:0.00}).\"\n            : $\"Support ground alignment: {delta:0.00} vertical offset applied \"\n              + \"(source feet unmapped; clip support aligned to target rest support).\");\n    }\n\n    private static Vector3 GroundUp(Vector3 up)\n    {\n        var absolute = Vector3.Abs(up);\n        return absolute.X >= absolute.Y && absolute.X >= absolute.Z\n            ? new Vector3(MathF.Sign(up.X), 0, 0)\n            : absolute.Y >= absolute.Z\n                ? new Vector3(0, MathF.Sign(up.Y), 0)\n                : new Vector3(0, 0, MathF.Sign(up.Z));\n    }\n\n    private static void ApplyRootMotion(\n        RootMotionMode mode, List<XForm[]> frames, TargetContext context, MappingReportInfo report)\n    {\n        if (mode == RootMotionMode.Off)\n            return;\n\n        if (context.HipsIndex is not { } hips)\n        {\n            AddNote(report, $\"Root motion ({mode}) skipped: target rig maps no Hips role.\");\n            return;\n        }\n        if (context.Up is not { } up)\n        {\n            AddNote(report, $\"Root motion ({mode}) skipped: {context.UpOrChainProblem}\");\n            return;\n        }\n\n        if (mode == RootMotionMode.Extract && context.DedicatedRootIndex is null)\n        {\n            // s&box-style target: pelvis is parentless and there is no separate translating\n            // root bone (root_IK is IkBaked). Bone-level extraction is impossible \u2014 the vmdl\n            // AnimFile entry carries an ExtractMotion node instead (compile-time extraction).\n            AddNote(report,\n                \"Root-motion extract: target has no dedicated animated root bone distinct from \"\n                + \"the hips; frames left as solved and motion extraction delegated to the vmdl \"\n                + \"AnimFile ExtractMotion node.\");\n            return;\n        }\n\n        var root = context.DedicatedRootIndex ?? hips;\n        var worldUp = GroundUp(up);\n        // Skeleton-aware overload: hips world via real parent-chain FK, locals re-derived\n        // against the actual parent (HipsParentIsRoot is ignored by this overload).\n        RootMotion.Apply(frames, context.Rig.Skeleton, new RootMotionAxes\n        {\n            // Match the world vertical used by support-height cleanup. A slightly\n            // leaning target torso must not tilt the plane used to remove travel;\n            // otherwise this final pass reintroduces vertical drift into grounded feet.\n            Up = worldUp,\n            RootIndex = root,\n            HipsIndex = hips,\n            HipsParentIsRoot = context.HipsParentIsRoot,\n        }, mode);\n        if (mode == RootMotionMode.InPlace && frames.Count > 0)\n        {\n            // Animation-only files may start far from their static reference pose.\n            // Removing travel alone freezes that offset into the clip, so blending\n            // directions moves the mesh away from its controller. Center every clip\n            // on the target bind hips, preserving vertical motion and local rotations.\n            var skeleton = context.Rig.Skeleton;\n            var center = Vector3.Zero;\n            foreach (var frame in frames)\n                center += FkUtil.BoneWorld(frame, skeleton, hips).Pos;\n            var offset = skeleton.RestWorld[hips].Pos - center / frames.Count;\n            offset -= Vector3.Dot(offset, worldUp) * worldUp;\n            foreach (var frame in frames)\n                for (var b = 0; b < skeleton.Count; b++)\n                    if (skeleton[b].ParentIndex < 0)\n                        frame[b] = new XForm(frame[b].Pos + offset, frame[b].Rot);\n        }\n        AddNote(report, mode == RootMotionMode.Extract\n            ? $\"Root motion extracted onto dedicated root bone (index {root}).\"\n            : \"Root motion removed (in-place clip).\");\n    }\n\n    private static void AddNote(MappingReportInfo report, string note)\n    {\n        if (!report.Notes.Contains(note))\n            report.Notes.Add(note);\n    }\n\n    /// <summary>\n    /// Mid-pose FBX sources: adopts the importer's bind-rest alternate skeleton when it\n    /// makes the character stand STRAIGHTER along the file's own up axis. Solving on a\n    /// posed rest breaks the solver's anatomical reasoning on exactly the posed limbs\n    /// (measured 48\u00b0 mean world-rot off ground truth on a real rig, left foot 124\u00b0); but\n    /// a bind rest can also tilt the character-up estimate (shoulders behind hips on one\n    /// real rig tilted it 7\u00b0, starving plant/stance detection), so the straighter rest\n    /// wins. Clips are authored playback either way \u2014 same bones, same order.\n    /// </summary>\n    private static SourceScene MaybeAdoptBindRest(\n        SourceScene scene, MappingResult map, MappingReportInfo report)\n    {\n        if (scene.MidPoseBindSkeleton is not { } bindSkeleton)\n            return scene;\n\n        var fileUp = scene.UpAxis switch\n        {\n            0 => new Vector3(scene.UpAxisSign, 0, 0),\n            2 => new Vector3(0, 0, scene.UpAxisSign),\n            _ => new Vector3(0, scene.UpAxisSign, 0),\n        };\n\n        float UpTiltDeg(SkeletonModel skeleton)\n        {\n            var (norm, _) = RestNormalizer.Normalize(skeleton, map);\n            var up = Vector3.Normalize(\n                CanonicalFrames.Build(skeleton, map, norm.WorldRest).CharacterUp);\n            return MathF.Acos(Math.Clamp(Vector3.Dot(up, fileUp), -1f, 1f)) * 180f / MathF.PI;\n        }\n\n        try\n        {\n            float tiltStatics = UpTiltDeg(scene.Skeleton);\n            float tiltBind = UpTiltDeg(bindSkeleton);\n            if (tiltBind > tiltStatics + 1f)\n            {\n                AddNote(report,\n                    $\"mid-pose export: kept the exported pose as rest - the file's bind \"\n                    + $\"data stands {tiltBind:0.#} deg off the file up axis \"\n                    + $\"(vs {tiltStatics:0.#} deg)\");\n                return scene;\n            }\n\n            AddNote(report,\n                \"mid-pose export: rest pose restored from the file's own bind data \"\n                + \"(clips keep their authored playback)\");\n            return new SourceScene(\n                bindSkeleton, scene.Clips, scene.UnitScaleCm,\n                scene.UpAxis, scene.UpAxisSign,\n                scene.FrontAxis, scene.FrontAxisSign,\n                scene.CoordAxis, scene.CoordAxisSign,\n                scene.OriginalUpAxis, scene.Notes)\n            {\n                AuthoredMapping = scene.AuthoredMapping,\n                RestPlacementAuthored = scene.RestPlacementAuthored,\n            };\n        }\n        catch (Exception)\n        {\n            // Anatomy not measurable (mapping lacks the frame's roles, degenerate rest):\n            // keep today's behavior.\n            return scene;\n        }\n    }\n\n    // ================================================================ import + mapping\n\n    /// <summary>\n    /// Imports source-file bytes exactly like conversion does: the extension picks the\n    /// importer; unknown extensions fall back to content sniffing (FBX binary magic / ASCII\n    /// header token / GLB 'glTF' magic / glTF JSON). Public so UI listings\n    /// inspect files through the SAME import path the pipeline uses (no duplicate sniffing\n    /// logic caller-side).\n    /// </summary>\n    /// <param name=\"data\">Raw file bytes.</param>\n    /// <param name=\"fileName\">File name; only the extension is consulted.</param>\n    /// <param name=\"sampleFps\">Resample rate for the imported clips; null = importer default\n    /// (30 fps).</param>\n    /// <exception cref=\"FormatException\">Thrown when the bytes are not a readable\n    /// motion, FBX or glTF animation.</exception>\n    public static SourceScene ImportSource(\n        byte[] data, string fileName, float? sampleFps = null,\n        Func<string, byte[]>? externalBufferResolver = null)\n    {\n        ArgumentNullException.ThrowIfNull(data);\n        ArgumentNullException.ThrowIfNull(fileName);\n\n        var fbxOptions = sampleFps is { } fbxFps ? new FbxImportOptions { SampleFps = fbxFps } : null;\n        var gltfOptions = sampleFps is not null || externalBufferResolver is not null\n            ? new GltfImportOptions\n            {\n                SampleFps = sampleFps ?? 30f,\n                ExternalBufferResolver = externalBufferResolver,\n            }\n            : null;\n        var ext = ExtensionOf(fileName);\n        return ext switch\n        {\n            \"hmotion\" => Motion.MotionDocument.Parse(data).ToSourceScene(sampleFps),\n            \"fbx\" => FbxImporter.Import(data, fbxOptions),\n            // .vrm = glTF 2.0 GLB container + VRM extension (the importer reads the authored\n            // humanoid bone map into SourceScene.AuthoredMapping); unknown-extension VRM\n            // bytes also land here via the GLB magic sniff below.\n            \"glb\" or \"gltf\" or \"vrm\" => GltfImporter.Import(data, gltfOptions),\n            _ => SniffFormat(data) switch\n            {\n                \"fbx\" => FbxImporter.Import(data, fbxOptions),\n                \"gltf\" => GltfImporter.Import(data, gltfOptions),\n                _ => throw new FormatException(\n                    $\"Unrecognized source format for '{fileName}' (expected .hmotion, .fbx, .glb, .gltf or .vrm).\"),\n            },\n        };\n    }\n\n    private static string? SniffFormat(byte[] data)\n    {\n        // Binary FBX magic: \"Kaydara FBX Binary  \\0\".\n        const string fbxMagic = \"Kaydara FBX Binary\";\n        if (StartsWithAscii(data, fbxMagic))\n            return \"fbx\";\n\n        // GLB magic: 'glTF' (0x46546C67 little-endian).\n        if (StartsWithAscii(data, \"glTF\"))\n            return \"gltf\";\n\n        var head = Encoding.UTF8.GetString(data, 0, Math.Min(data.Length, 4096));\n        if (head.Contains(\"FBXHeaderExtension\", StringComparison.Ordinal))\n            return \"fbx\"; // ASCII FBX\n        var trimmed = head.TrimStart();\n        if (trimmed.StartsWith(\"{\", StringComparison.Ordinal)\n            && head.Contains(\"\\\"asset\\\"\", StringComparison.Ordinal))\n            return \"gltf\"; // plain-JSON glTF\n        return null;\n    }\n\n    private static bool StartsWithAscii(byte[] data, string prefix)\n    {\n        if (data.Length < prefix.Length)\n            return false;\n        for (var i = 0; i < prefix.Length; i++)\n        {\n            if (data[i] != (byte)prefix[i])\n                return false;\n        }\n        return true;\n    }\n\n    /// <summary>\n    /// THE mapping cascade, shared by conversion, UI file listings, and custom-target\n    /// detection: explicit override \u2192 authored mapping (from the file itself, e.g. a VRM's\n    /// humanoid bone map \u2014 authoritative ground truth at confidence 1.0) \u2192 user preset (via\n    /// <paramref name=\"userPresetLookup\"/>, keyed by <see cref=\"Mapping.SkeletonSignature\"/>)\n    /// \u2192 shipped preset detection \u2192 best-effort auto-map. The report's\n    /// <see cref=\"MappingReportInfo.NeedsUserDecision\"/> is true only on the auto path below\n    /// the preset detection threshold \u2014 conversion still proceeds with that map; callers\n    /// decide whether to ask/reject.\n    /// </summary>\n    /// <param name=\"skeleton\">Source (or candidate target) skeleton.</param>\n    /// <param name=\"mappingOverride\">Explicit mapping (manual table / already-resolved user\n    /// preset); wins outright when non-null \u2014 a deliberate user decision beats even the\n    /// file's own bone map.</param>\n    /// <param name=\"userPresetLookup\">Editor-side user-preset hook: receives the skeleton's\n    /// signature, returns the stored mapping or null. The facade itself can do no file IO.</param>\n    /// <param name=\"authoredMapping\">A mapping authored INSIDE the source file\n    /// (<see cref=\"SourceScene.AuthoredMapping\"/>, <see cref=\"MappingSource.Authored\"/>);\n    /// consulted before user presets because the file itself is authoritative.</param>\n    public static (MappingResult Map, MappingReportInfo Report) ResolveMapping(\n        SkeletonModel skeleton, MappingResult? mappingOverride = null,\n        Func<string, MappingResult?>? userPresetLookup = null,\n        MappingResult? authoredMapping = null)\n    {\n        ArgumentNullException.ThrowIfNull(skeleton);\n\n        if (mappingOverride is not null)\n            return (mappingOverride, BuildReport(mappingOverride, needsUserDecision: false, skeleton));\n\n        if (authoredMapping is not null)\n            return (authoredMapping, BuildReport(authoredMapping, needsUserDecision: false, skeleton));\n\n        if (userPresetLookup is not null\n            && userPresetLookup(Mapping.SkeletonSignature.Compute(skeleton)) is { } userPreset)\n            return (userPreset, BuildReport(userPreset, needsUserDecision: false, skeleton));\n\n        if (ProfileDetector.Detect(skeleton) is { } detected)\n        {\n            AutoMapper.CompleteSingleJointThumbs(skeleton, detected.Result);\n            AutoMapper.CompleteFingersByTopology(skeleton, detected.Result);\n            AutoMapper.PruneNonArticulatedFingerStubs(skeleton, detected.Result);\n            VetoImpossibleHead(skeleton, detected.Result);\n            return (detected.Result, BuildReport(detected.Result, needsUserDecision: false, skeleton));\n        }\n\n        var auto = AutoMapper.Map(skeleton);\n        VetoImpossibleHead(skeleton, auto);\n        var needsUserDecision = auto.Confidence < ProfileDetector.DetectionThreshold;\n        return (auto, BuildReport(auto, needsUserDecision, skeleton));\n    }\n\n    /// <summary>\n    /// Drops a detected/auto-mapped Head whose bone cannot anatomically drive a skull: its\n    /// rest sits clearly BELOW the neck (or the topmost mapped spine joint). Real case: an\n    /// Auto-Rig Pro export parks <c>head.x</c> at chest height ~90cm under <c>neck.x</c>\n    /// with the skin bind compensating \u2014 the mesh is correct at rest, but every skull\n    /// rotation replayed onto that bone sweeps the head geometry on the lever arm (\"the\n    /// head is stretched and it stretched more when I played the animation\"). With the\n    /// role unmapped the neck \u2014 whose pivot IS at the skull base on such rigs \u2014 carries\n    /// head motion, and the bone holds its rest like any other unmapped helper.\n    /// Neutral-rest corpus rigs measure the neck\u2192head segment \u22128\u00b0\u202633\u00b0 from character up\n    /// (dot \u2265 0.55 even on the posed Defenses bind at 40.7\u00b0); the veto fires only past\n    /// 101\u00b0 (dot &lt; \u22120.2), an impossible carriage on any working rig. Explicit,\n    /// authored and user-preset mappings are authoritative and never second-guessed.\n    /// </summary>\n    private static void VetoImpossibleHead(SkeletonModel skeleton, MappingResult map)\n    {\n        if (!map.RoleToBone.TryGetValue(BoneRole.Head, out var head)\n            || !map.RoleToBone.TryGetValue(BoneRole.Hips, out var hips))\n            return;\n\n        var reference = map.RoleToBone.TryGetValue(BoneRole.Neck, out var neck)\n            ? neck\n            : SpineTop(map);\n        if (reference is not { } refBone || refBone == hips)\n            return;\n\n        var rest = skeleton.RestWorld;\n        // Axis-free \"up\": the body chain ascends hips \u2192 spine \u2192 neck by construction, so\n        // hips\u2192reference is the rig's own vertical regardless of world axis convention.\n        var up = rest[refBone].Pos - rest[hips].Pos;\n        var seg = rest[head].Pos - rest[refBone].Pos;\n        if (up.LengthSquared() < 1e-6f || seg.Length() < 0.05f * up.Length())\n            return; // degenerate spine / head stacked on the neck: nothing to judge\n\n        if (Vector3.Dot(Vector3.Normalize(seg), Vector3.Normalize(up)) >= -0.2f)\n            return;\n\n        map.RoleToBone.Remove(BoneRole.Head);\n        // The neck of a broken skull region rests with the head. On the real case the\n        // neck bone skins the skull AND a torso column (its weights are where the head's\n        // should be), so any solved neck bend shears half the body: the source spreads\n        // its idle hunch through its spine while this target's spine stays put, and the\n        // faithful neck world replay turned into a ~19\u00b0 LOCAL kink rendered as a hump\n        // grafted onto the character's back. Skull attitude rides the spine instead.\n        var neckNote = \"\";\n        if (map.RoleToBone.Remove(BoneRole.Neck))\n            neckNote = $\" Its neck '{skeleton[neck].Name}' rests too (on such exports it \"\n                + \"carries the skull/torso skin the head joint should).\";\n        map.Notes.Add(\n            $\"Head '{skeleton[head].Name}' unmapped: its rest sits below \"\n            + $\"'{skeleton[refBone].Name}' - not a skull joint the solver can drive \"\n            + \"(rotations would sweep the head geometry on the offset lever arm).\"\n            + neckNote + \" The spine carries the upper body; map manually to override.\");\n    }\n\n    private static int? SpineTop(MappingResult map)\n    {\n        foreach (var role in new[]\n        {\n            BoneRole.Spine4, BoneRole.Spine3, BoneRole.Spine2, BoneRole.Spine1, BoneRole.Spine0,\n        })\n        {\n            if (map.RoleToBone.TryGetValue(role, out var bone))\n                return bone;\n        }\n        return null;\n    }\n\n    private static MappingReportInfo BuildReport(\n        MappingResult map, bool needsUserDecision, SkeletonModel skeleton)\n    {\n        var report = new MappingReportInfo\n        {\n            ProfileName = map.ProfileName,\n            Source = map.Source,\n            Confidence = map.Confidence,\n            NeedsUserDecision = needsUserDecision,\n            MappedRoleCount = map.RoleToBone.Count,\n            SkeletonSignature = Mapping.SkeletonSignature.Compute(skeleton),\n        };\n        report.Notes.AddRange(map.Notes);\n        if (needsUserDecision)\n            report.Notes.Add(\n                $\"No preset profile matched and auto-map confidence {map.Confidence:0.00} is below \"\n                + $\"{ProfileDetector.DetectionThreshold:0.00}; proceeding with the best-effort auto map.\");\n        return report;\n    }\n\n    // ================================================================ naming\n\n    private static string RequestedClipName(RetargetRequest request, SourceScene scene, int take)\n    {\n        var multipleTakes = scene.Clips.Count > 1;\n        if (!string.IsNullOrWhiteSpace(request.ClipNameOverride))\n            return multipleTakes ? $\"{request.ClipNameOverride}_{take + 1}\" : request.ClipNameOverride!;\n\n        var takeName = scene.Clips[take].Name;\n        if (!string.IsNullOrWhiteSpace(takeName) && takeName != \"motion\"\n            && !takeName.Equals(\"mixamo.com\", StringComparison.OrdinalIgnoreCase)\n            && !IsExporterPlaceholderTake(takeName))\n            return takeName;\n\n        // BVH files (clip always named \"motion\"), Mixamo takes (always named\n        // \"mixamo.com\"), Unreal exports (every stack named \"Unreal Take\") and\n        // unnamed takes use the file stem.\n        var stem = FileStem(request.SourceFileName);\n        return multipleTakes ? $\"{stem}_{take + 1}\" : stem;\n    }\n\n    /// <summary>\n    /// True for take names that identify the EXPORTER rather than the animation. Unreal's\n    /// FBX exporter stamps <c>Unreal Take</c> into every AnimStack it writes (numbered \u2014\n    /// <c>Unreal Take 001</c> \u2014 when a sequence exports several), so a folder of UE clips\n    /// arrives with one identical take name on every file. Treated as authored, that name\n    /// beats the file stem in <see cref=\"RequestedClipName\"/> and the whole batch collapses\n    /// onto one clip name, which <see cref=\"UniqueClipName\"/> then has to pull apart into\n    /// <c>Unreal_Take</c>, <c>Unreal_Take_2</c>, <c>Unreal_Take_3</c>\u2026 \u2014 every file's real\n    /// name lost, and the resulting sequence names carry no meaning in the vmdl. Falling\n    /// through to the file stem restores the same per-file naming BVH and Mixamo sources\n    /// already get. Matched as a PREFIX, and against the underscored spelling too, so the\n    /// numbered variants and any already-sanitized re-import are covered.\n    /// </summary>\n    private static bool IsExporterPlaceholderTake(string takeName)\n    {\n        var trimmed = takeName.Trim();\n        return trimmed.StartsWith(\"unreal take\", StringComparison.OrdinalIgnoreCase)\n            || trimmed.StartsWith(\"unreal_take\", StringComparison.OrdinalIgnoreCase);\n    }\n\n    /// <summary>Collision auto-suffixing across the batch: <c>name</c>, <c>name_2</c>, \u2026\n    /// (case-insensitive \u2014 the names also become DMX file names).</summary>\n    private static string UniqueClipName(string name, HashSet<string> usedNames, bool autoSuffix)\n    {\n        if (usedNames.Add(name) || !autoSuffix)\n            return name;\n        for (var i = 2; ; i++)\n        {\n            var candidate = $\"{name}_{i}\";\n            if (usedNames.Add(candidate))\n                return candidate;\n        }\n    }\n\n    /// <summary>\n    /// Clip names become ModelDoc AnimFile node names and Source 2 sequence names, which\n    /// must stay within <c>[A-Za-z0-9_]</c> \u2014 a take name like <c>mixamo.com</c> otherwise\n    /// fails the vmdl compile with \"Node 'mixamo.com' resolve failure\". Runs of invalid\n    /// characters collapse to a single underscore; case is preserved. Public so UIs that\n    /// dry-run name-based detection (e.g. the locomotion-set scan over raw take names) see\n    /// the SAME spelling conversion will produce \u2014 a take named <c>Walk N</c> becomes the\n    /// clip <c>Walk_N</c>.\n    /// </summary>\n    public static string SanitizeClipName(string name)\n    {\n        var builder = new StringBuilder(name.Length);\n        var lastWasUnderscore = false;\n        foreach (var c in name)\n        {\n            if (c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or (>= '0' and <= '9') or '_')\n            {\n                builder.Append(c);\n                lastWasUnderscore = c == '_';\n            }\n            else if (!lastWasUnderscore)\n            {\n                builder.Append('_');\n                lastWasUnderscore = true;\n            }\n        }\n        var sanitized = builder.ToString().Trim('_');\n        return sanitized.Length > 0 ? sanitized : \"clip\";\n    }\n\n    private static string FileStem(string fileName)\n    {\n        var start = Math.Max(fileName.LastIndexOf('/'), fileName.LastIndexOf('\\\\')) + 1;\n        var dot = fileName.LastIndexOf('.');\n        var end = dot > start ? dot : fileName.Length;\n        var stem = fileName.Substring(start, end - start);\n        return stem.Length > 0 ? stem : \"clip\";\n    }\n\n    private static string ExtensionOf(string fileName)\n    {\n        var dot = fileName.LastIndexOf('.');\n        if (dot < 0 || dot == fileName.Length - 1)\n            return \"\";\n        var ext = fileName.Substring(dot + 1);\n        return ext.IndexOfAny(new[] { '/', '\\\\' }) >= 0 ? \"\" : ext.ToLowerInvariant();\n    }\n\n    private static string SanitizeFileName(string name)\n    {\n        var builder = new StringBuilder(name.Length);\n        foreach (var c in name)\n        {\n            builder.Append(\n                c is (>= 'a' and <= 'z') or (>= '0' and <= '9') or '_' or '-' ? c\n                : c is >= 'A' and <= 'Z' ? char.ToLowerInvariant(c)\n                : '_');\n        }\n        var sanitized = builder.ToString().Trim('_');\n        return sanitized.Length > 0 ? sanitized : \"clip\";\n    }\n\n    private static string JoinAssetPath(string folder, string file)\n    {\n        var f = folder.Replace('\\\\', '/').TrimEnd('/');\n        return f.Length == 0 ? file : f + \"/\" + file;\n    }\n\n    // ================================================================ target context\n\n    /// <summary>Everything derived once per batch from the target rig: character up axis,\n    /// foot chains, hips/root indices, IK-bone presence.</summary>\n    internal sealed class TargetContext\n    {\n        public TargetRig Rig { get; }\n\n        /// <summary>Target character up direction (midShoulders \u2212 midHips on the rest pose,\n        /// via <see cref=\"CharacterFrame\"/>); null when the rig lacks the bones for it.</summary>\n        public Vector3? Up { get; }\n\n        /// <summary>Target character frame (for the arm-IK basis change); null when not computable.</summary>\n        public CharacterFrame? Frame { get; }\n\n        /// <summary>Left/right leg chains from the rig's UpperLeg/LowerLeg/Foot/Toe roles;\n        /// null when either leg is incompletely mapped.</summary>\n        public (FootChain Left, FootChain Right)? FootChains { get; }\n\n        /// <summary>Why <see cref=\"Up\"/> / <see cref=\"FootChains\"/> are unavailable (report note text).</summary>\n        public string UpOrChainProblem { get; } = \"\";\n\n        /// <summary>Target bone carrying the Hips role.</summary>\n        public int? HipsIndex { get; }\n\n        /// <summary>Dedicated translating root: a parentless Animated bone that is an\n        /// ancestor of (and distinct from) the hips. Null on the s&amp;box rig (pelvis is\n        /// itself parentless; root_IK is IkBaked).</summary>\n        public int? DedicatedRootIndex { get; }\n\n        /// <summary>True when the hips bone's direct parent is the dedicated root.</summary>\n        public bool HipsParentIsRoot { get; }\n\n        public bool HasIkBakedBones { get; }\n\n        /// <summary>ConstraintDriven bone indices (twist/helper) \u2014 excluded from DMX\n        /// channels per design \u00a73; null when the rig has none. Face bones\n        /// (<see cref=\"SboxBoneClassifier.IsFaceBone\"/>) are NOT in this set even though\n        /// their class is ConstraintDriven: they keep rest-local channels, because no\n        /// constraint re-drives them in a compiled sequence (channel-less face joints\n        /// bake statically \u2014 eyes detach from the moving head in ModelDoc).</summary>\n        public IReadOnlySet<int>? ConstraintDrivenBones { get; }\n\n        public TargetContext(TargetRig rig)\n        {\n            Rig = rig;\n            HipsIndex = rig.BoneForRole(BoneRole.Hips);\n            DedicatedRootIndex = FindDedicatedRoot(rig, HipsIndex);\n            HipsParentIsRoot = HipsIndex is { } hips && DedicatedRootIndex is { } root\n                && rig.Skeleton[hips].ParentIndex == root;\n            foreach (var _ in rig.BonesOfClass(BoneClass.IkBaked))\n            {\n                HasIkBakedBones = true;\n                break;\n            }\n\n            var constraintDriven = new HashSet<int>(rig.BonesOfClass(BoneClass.ConstraintDriven));\n            // Face bones (eye_/ear_/face_) are ConstraintDriven by class but, unlike the\n            // twist/helper bones, nothing re-drives them when a compiled sequence plays:\n            // the model's AnimConstraintList never references them and the engine's eye\n            // look-at / blinking only runs in game. They must KEEP their rest-local DMX\n            // channels (the shipped fbx2dmx clips carry them too) or ModelDoc bakes the\n            // channel-less joints statically and the eyes detach from the moving head\n            // (see SboxBoneClassifier.IsFaceBone).\n            constraintDriven.RemoveWhere(i => SboxBoneClassifier.IsFaceBone(rig.Skeleton[i].Name));\n            ConstraintDrivenBones = constraintDriven.Count > 0 ? constraintDriven : null;\n\n            try\n            {\n                Frame = CharacterFrame.Compute(rig.Skeleton, rig.ToMappingResult(), rig.Skeleton.RestWorld);\n                Up = Frame.Up;\n            }\n            catch (ArgumentException e)\n            {\n                UpOrChainProblem = $\"target character frame not computable ({e.Message})\";\n                return;\n            }\n\n            var left = LegChain(rig, BoneRole.UpperLegL, BoneRole.LowerLegL, BoneRole.FootL, BoneRole.ToeL);\n            var right = LegChain(rig, BoneRole.UpperLegR, BoneRole.LowerLegR, BoneRole.FootR, BoneRole.ToeR);\n            if (left is not null && right is not null)\n                FootChains = (left, right);\n            else\n                UpOrChainProblem = \"target rig does not map a complete UpperLeg/LowerLeg/Foot chain on both sides\";\n        }\n\n        private static FootChain? LegChain(TargetRig rig, BoneRole upper, BoneRole lower, BoneRole foot, BoneRole toe)\n            => rig.BoneForRole(upper) is { } hip\n               && rig.BoneForRole(lower) is { } knee\n               && rig.BoneForRole(foot) is { } ankle\n                ? new FootChain { Hip = hip, Knee = knee, Ankle = ankle, Toe = rig.BoneForRole(toe) }\n                : null;\n\n        private static int? FindDedicatedRoot(TargetRig rig, int? hipsIndex)\n        {\n            if (hipsIndex is not { } hips)\n                return null;\n            // Walk up from the hips; the topmost ancestor qualifies when it is a parentless\n            // Animated bone distinct from the hips itself.\n            var top = hips;\n            while (rig.Skeleton[top].ParentIndex >= 0)\n                top = rig.Skeleton[top].ParentIndex;\n            return top != hips && rig.ClassOf(top) == BoneClass.Animated ? top : null;\n        }\n    }\n\n    // ================================================================ arm effector IK\n\n    /// <summary>\n    /// Optional wrist-reach cleanup: per frame, the source hand offset from its shoulder is\n    /// limb-length-normalized, re-expressed in the target's character basis, and used as a\n    /// two-bone IK goal for the target arm (<see cref=\"EffectorIk.ApplyGoals\"/>).\n    /// </summary>\n    private static class ArmIkCleanup\n    {\n        /// <summary>Runs both arms; returns a problem note (and does nothing) when the\n        /// prerequisites are missing, null on success.</summary>\n        public static string? Apply(\n            List<XForm[]> frames, SourceScene scene, MappingResult map,\n            TargetRig rig, TargetContext context, int take)\n        {\n            if (context.Frame is not { } targetFrame)\n                return context.UpOrChainProblem;\n\n            CharacterFrame sourceFrame;\n            try\n            {\n                sourceFrame = CharacterFrame.Compute(scene.Skeleton, map, scene.Skeleton.RestWorld);\n            }\n            catch (ArgumentException e)\n            {\n                return $\"source character frame not computable ({e.Message})\";\n            }\n\n            // Change of basis source space \u2192 target space (this library's convention:\n            // a * b applies b first).\n            var sourceToTarget = MathQ.Normalize(\n                BasisRotation(targetFrame) * Quaternion.Conjugate(BasisRotation(sourceFrame)));\n\n            var appliedAny = false;\n            appliedAny |= ApplyArm(frames, scene, map, rig, sourceToTarget, take,\n                BoneRole.UpperArmL, BoneRole.LowerArmL, BoneRole.HandL);\n            appliedAny |= ApplyArm(frames, scene, map, rig, sourceToTarget, take,\n                BoneRole.UpperArmR, BoneRole.LowerArmR, BoneRole.HandR);\n            return appliedAny ? null : \"no complete UpperArm/LowerArm/Hand chain mapped on source and target\";\n        }\n\n        private static bool ApplyArm(\n            List<XForm[]> frames, SourceScene scene, MappingResult map, TargetRig rig,\n            Quaternion sourceToTarget, int take, BoneRole upperRole, BoneRole lowerRole, BoneRole handRole)\n        {\n            if (!map.RoleToBone.TryGetValue(upperRole, out var srcUpper)\n                || !map.RoleToBone.TryGetValue(lowerRole, out var srcLower)\n                || !map.RoleToBone.TryGetValue(handRole, out var srcHand))\n                return false;\n            if (rig.BoneForRole(upperRole) is not { } tgtUpper\n                || rig.BoneForRole(lowerRole) is not { } tgtLower\n                || rig.BoneForRole(handRole) is not { } tgtHand)\n                return false;\n\n            var src = scene.Skeleton;\n            var tgt = rig.Skeleton;\n            var srcLen = Vector3.Distance(src.RestWorld[srcUpper].Pos, src.RestWorld[srcLower].Pos)\n                       + Vector3.Distance(src.RestWorld[srcLower].Pos, src.RestWorld[srcHand].Pos);\n            var tgtLen = Vector3.Distance(tgt.RestWorld[tgtUpper].Pos, tgt.RestWorld[tgtLower].Pos)\n                       + Vector3.Distance(tgt.RestWorld[tgtLower].Pos, tgt.RestWorld[tgtHand].Pos);\n            if (srcLen < 1e-4f || tgtLen < 1e-4f)\n                return false;\n            var scale = tgtLen / srcLen;\n\n            var sourceFrames = scene.Clips[take].Frames;\n            var count = Math.Min(frames.Count, sourceFrames.Count);\n            var goals = new Vector3[frames.Count];\n            for (var f = 0; f < frames.Count; f++)\n            {\n                var srcWorld = new Pose(sourceFrames[Math.Min(f, count - 1)]).ToWorld(src);\n                var tgtWorld = new Pose(frames[f]).ToWorld(tgt);\n                var reach = srcWorld[srcHand].Pos - srcWorld[srcUpper].Pos;\n                goals[f] = tgtWorld[tgtUpper].Pos + Vector3.Transform(reach, sourceToTarget) * scale;\n            }\n\n            EffectorIk.ApplyGoals(\n                frames, tgt,\n                new LimbChain { Upper = tgtUpper, Lower = tgtLower, End = tgtHand },\n                goals, RestBendAxis(tgt, tgtUpper, tgtLower, tgtHand));\n            return true;\n        }\n\n        /// <summary>Hinge-axis fallback from the rest bend plane (elbow), like the foot pass.</summary>\n        internal static Vector3 RestBendAxis(SkeletonModel skeleton, int upper, int lower, int end)\n        {\n            var a = skeleton.RestWorld[upper].Pos;\n            var b = skeleton.RestWorld[lower].Pos;\n            var c = skeleton.RestWorld[end].Pos;\n            var axis = Vector3.Cross(c - a, b - a);\n            if (axis.LengthSquared() > 1e-6f)\n                return Vector3.Normalize(axis);\n            var limb = c - a;\n            axis = Vector3.Cross(limb, Vector3.UnitY);\n            if (axis.LengthSquared() < 1e-6f)\n                axis = Vector3.Cross(limb, Vector3.UnitZ);\n            return axis.LengthSquared() > 1e-12f ? Vector3.Normalize(axis) : Vector3.UnitX;\n        }\n\n        /// <summary>Rotation taking canonical character axes (X=lateral, Y=up, Z=forward)\n        /// to the rig's world axes.</summary>\n        private static Quaternion BasisRotation(CharacterFrame frame)\n        {\n            var m = new Matrix4x4(\n                frame.Lateral.X, frame.Lateral.Y, frame.Lateral.Z, 0f,\n                frame.Up.X, frame.Up.Y, frame.Up.Z, 0f,\n                frame.Forward.X, frame.Forward.Y, frame.Forward.Z, 0f,\n                0f, 0f, 0f, 1f);\n            return MathQ.Normalize(Quaternion.CreateFromRotationMatrix(m));\n        }\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Skeleton/Skeleton.cs",
            "FileName": "Skeleton.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Collections.Generic;\nusing HumanoidMocapX.Core.Maths;\n\nnamespace HumanoidMocapX.Core.Skeleton;\n\n/// <summary>\n/// Immutable bone hierarchy with rest pose. Bones are stored topologically sorted\n/// (every bone's parent precedes it), which lets forward kinematics run as a single\n/// in-order pass. Supports multiple roots (e.g. the s&amp;box rig has both\n/// <c>root_IK</c> and <c>pelvis</c> as parentless bones).\n/// </summary>\npublic sealed class Skeleton\n{\n    private readonly Bone[] _bones;\n    private readonly XForm[] _restWorld;\n    private readonly Dictionary<string, int> _indexByName;\n\n    private Skeleton(Bone[] bones, XForm[] restWorld, Dictionary<string, int> indexByName)\n    {\n        _bones = bones;\n        _restWorld = restWorld;\n        _indexByName = indexByName;\n    }\n\n    /// <summary>Number of bones.</summary>\n    public int Count => _bones.Length;\n\n    /// <summary>All bones, topologically sorted (parents before children).</summary>\n    public IReadOnlyList<Bone> Bones => _bones;\n\n    /// <summary>Rest (bind) world transforms, indexed like <see cref=\"Bones\"/>.</summary>\n    public IReadOnlyList<XForm> RestWorld => _restWorld;\n\n    /// <summary>Bone name to index lookup.</summary>\n    public IReadOnlyDictionary<string, int> IndexByName => _indexByName;\n\n    /// <summary>The bone at <paramref name=\"index\"/>.</summary>\n    public Bone this[int index] => _bones[index];\n\n    /// <summary>Returns the index of the named bone, or -1 when absent.</summary>\n    public int IndexOf(string name) => _indexByName.TryGetValue(name, out var index) ? index : -1;\n\n    /// <summary>\n    /// Builds a skeleton from bone definitions in any order: validates names and parent links,\n    /// topologically sorts (stable \u2014 input order is preserved among bones whose parents are\n    /// already placed), and computes rest world transforms.\n    /// </summary>\n    /// <exception cref=\"ArgumentException\">\n    /// Thrown on duplicate bone names, unknown parent names, or parent cycles.\n    /// </exception>\n    public static Skeleton Create(IReadOnlyList<BoneDefinition> definitions)\n    {\n        ArgumentNullException.ThrowIfNull(definitions);\n\n        var count = definitions.Count;\n        var originalIndexByName = new Dictionary<string, int>(count, StringComparer.Ordinal);\n        for (var i = 0; i < count; i++)\n        {\n            var name = definitions[i].Name;\n            if (string.IsNullOrEmpty(name))\n                throw new ArgumentException($\"Bone at position {i} has an empty name.\", nameof(definitions));\n            if (!originalIndexByName.TryAdd(name, i))\n                throw new ArgumentException($\"Duplicate bone name '{name}'.\", nameof(definitions));\n        }\n\n        foreach (var def in definitions)\n        {\n            if (def.ParentName is not null && !originalIndexByName.ContainsKey(def.ParentName))\n                throw new ArgumentException(\n                    $\"Bone '{def.Name}' references unknown parent '{def.ParentName}'.\", nameof(definitions));\n            if (def.ParentName == def.Name)\n                throw new ArgumentException($\"Bone '{def.Name}' is its own parent.\", nameof(definitions));\n        }\n\n        // Stable topological sort: repeatedly place, in input order, every bone whose parent\n        // is already placed. O(n^2) worst case \u2014 fine for skeleton-sized inputs (~100 bones).\n        var newIndexByOriginal = new int[count];\n        Array.Fill(newIndexByOriginal, -1);\n        var order = new List<int>(count);\n        while (order.Count < count)\n        {\n            var progressed = false;\n            for (var i = 0; i < count; i++)\n            {\n                if (newIndexByOriginal[i] >= 0)\n                    continue;\n                var parentName = definitions[i].ParentName;\n                if (parentName is not null && newIndexByOriginal[originalIndexByName[parentName]] < 0)\n                    continue;\n                newIndexByOriginal[i] = order.Count;\n                order.Add(i);\n                progressed = true;\n            }\n            if (!progressed)\n                throw new ArgumentException(\"Bone hierarchy contains a parent cycle.\", nameof(definitions));\n        }\n\n        var bones = new Bone[count];\n        var restWorld = new XForm[count];\n        var indexByName = new Dictionary<string, int>(count, StringComparer.Ordinal);\n        for (var newIndex = 0; newIndex < count; newIndex++)\n        {\n            var def = definitions[order[newIndex]];\n            var parentIndex = def.ParentName is null ? -1 : newIndexByOriginal[originalIndexByName[def.ParentName]];\n            bones[newIndex] = new Bone(newIndex, def.Name, parentIndex, def.RestLocal);\n            restWorld[newIndex] = parentIndex < 0\n                ? def.RestLocal\n                : XForm.Compose(restWorld[parentIndex], def.RestLocal);\n            indexByName.Add(def.Name, newIndex);\n        }\n\n        return new Skeleton(bones, restWorld, indexByName);\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "HumanoidMocap/Core/Target/KvBool.cs",
            "FileName": "KvBool.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Text;\n\nnamespace HumanoidMocapX.Core.Target;\n\n/// <summary>A KV3 boolean.</summary>\npublic sealed class KvBool : KvValue\n{\n    /// <summary>The boolean value.</summary>\n    public bool Value { get; }\n\n    /// <summary>Creates a boolean value.</summary>\n    public KvBool(bool value) => Value = value;\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "dev/clip_checks.cs",
            "FileName": "clip_checks.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System.Diagnostics;\nusing System.Text;\nusing System.Text.Json;\nusing HumanoidMocapX.Core;\nusing HumanoidMocapX.Core.Formats.Fbx;\nusing HumanoidMocapX.Core.Motion;\nusing HumanoidMocapX.Core.Target;\nusing HumanoidMocapX.EditorTools;\nusing HumanoidMocapX.Inference;\nusing Sandbox;\nusing static Sandbox.Internal.GlobalGameNamespace;\n\nnamespace HumanoidMocapX.Checks;\n\n/// <summary>Runs the full model sequence on a 5\u201310-second predecoded video fixture.\n/// This developer check excludes production decoding and visual motion acceptance.</summary>\npublic static class ClipChecks\n{\n    public sealed record Fixture(string RgbaPath, int Width, int Height, int Frames, string SourceVideo,\n        string FlowPath, string SamPath, string MhrPath, string OmegaPath, string DetectorPath, string SmplPath, string RigDirectory,\n        int CameraInterval = 10, FlowModel Model = FlowModel.Latest);\n\n    /// <summary>Writes per-stage evidence, motion documents and Human/Citizen FBX\n    /// exports. Requires installed released weights and a fresh writable result directory.</summary>\n    public static async Task<object> Run(string fixturePath, string directory, CancellationToken cancellation)\n    {\n        var fixture = JsonSerializer.Deserialize<Fixture>(await File.ReadAllTextAsync(fixturePath, cancellation))\n            ?? throw new ArgumentException(\"Missing clip fixture.\");\n        if (fixture.Frames is < 150 or > 300) throw new ArgumentException(\"Clip validation requires 5\u201310 seconds at 30 fps.\");\n        if (Directory.Exists(directory)) throw new ArgumentException(\"Use a fresh validation directory to avoid overwriting evidence.\");\n        Directory.CreateDirectory(directory);\n        await File.WriteAllTextAsync(Path.Combine(directory, \"fixture.json\"), JsonSerializer.Serialize(fixture), cancellation);\n        var processor = Processor(fixture); using var frames = new RawFrames(fixture);\n        await Task.Run(() => FlowCheckpoint.LoadDecoder(fixture.FlowPath, fixture.SmplPath, cancellation), cancellation);\n        var timer = Stopwatch.StartNew(); var times = new Dictionary<string, double>();\n        var person = await processor.DetectAsync(frames, cancellation); times[\"Detection\"] = timer.Elapsed.TotalSeconds;\n        if (person.First != 0 || person.Count != frames.Count) throw new InvalidDataException(\"The validation fixture must show the person in every frame.\");\n        var boxes = person.Boxes; await Save(\"boxes.json\", boxes); await Save(\"timings.json\", times); timer.Restart();\n        var camera = await processor.CameraAsync(frames, cancellation); times[\"Camera\"] = timer.Elapsed.TotalSeconds;\n        await Save(\"rotations.json\", camera.Rotations); await Save(\"intrinsics.json\", camera.Intrinsics); await Save(\"travel.json\", camera.Travel); await Save(\"timings.json\", times); timer.Restart();\n        var (features, observations) = await processor.FeaturesAsync(frames, boxes, camera.Intrinsics, cancellation); times[\"Features\"] = timer.Elapsed.TotalSeconds;\n        await Save(\"features.json\", features); await Save(\"observations.json\", observations); await Save(\"timings.json\", times); timer.Restart();\n        var motion = await processor.GenerateAsync(features, camera.Rotations, frames.Count, cancellation); times[\"Generation\"] = timer.Elapsed.TotalSeconds;\n        var exports = await Export(fixture, motion, new ObservedDetail(observations, camera.Rotations, camera.Travel), directory, cancellation); await Save(\"timings.json\", times);\n        var result = new { Passed = true, PredecodedFixture = true, Frames = frames.Count, Seconds = frames.Count / 30.0, StageSeconds = times, Exports = exports };\n        await Save(\"result.json\", result);\n        return result;\n\n        Task Save<T>(string name, T value) => File.WriteAllTextAsync(Path.Combine(directory, name), JsonSerializer.Serialize(value), cancellation);\n    }\n\n    /// <summary>Repeats generation/export from this check's saved features. For\n    /// developer diagnosis only: the caller must preserve the same fixture and weights.</summary>\n    public static async Task<object> Generate(string directory, CancellationToken cancellation)\n    {\n        var fixture = JsonSerializer.Deserialize<Fixture>(await File.ReadAllTextAsync(Path.Combine(directory, \"fixture.json\"), cancellation));\n        var features = JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(Path.Combine(directory, \"features.json\"), cancellation));\n        var rotations = JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(Path.Combine(directory, \"rotations.json\"), cancellation));\n        var motion = await Processor(fixture).GenerateAsync(features, rotations, fixture.Frames, cancellation);\n        var observed = Path.Combine(directory, \"observations.json\");\n        var traveled = Path.Combine(directory, \"travel.json\");\n        var travel = File.Exists(traveled) ? JsonSerializer.Deserialize<float>(await File.ReadAllTextAsync(traveled, cancellation)) : float.NaN;\n        var detail = File.Exists(observed) ? new ObservedDetail(JsonSerializer.Deserialize<float[]>(await File.ReadAllTextAsync(observed, cancellation)), rotations, travel) : null;\n        return await Export(fixture, motion, detail, directory, cancellation);\n    }\n\n    static FlowVideoProcessor Processor(Fixture fixture) => new(new(fixture.FlowPath, fixture.SamPath, fixture.MhrPath, fixture.OmegaPath, fixture.DetectorPath, fixture.SmplPath),\n        new() { CameraInterval = fixture.CameraInterval, Model = fixture.Model }, message => Log.Info(message));\n\n    static Task<object> Export(Fixture fixture, FlowMotion motion, ObservedDetail detail, string directory, CancellationToken cancellation) => Task.Run<object>(async () =>\n    {\n        motion.Video = fixture.SourceVideo; motion.Name = Path.GetFileNameWithoutExtension(fixture.SourceVideo); var document = motion.ToDocument(); detail?.Apply(document);\n        var bytes = Encoding.UTF8.GetBytes(document.ToJson()); await File.WriteAllBytesAsync(Path.Combine(directory, \"capture.hmotion\"), bytes, cancellation);\n        await File.WriteAllTextAsync(Path.Combine(directory, \"flow-motion.json\"), JsonSerializer.Serialize(motion), cancellation);\n        var results = new List<object>();\n        foreach (var citizen in new[] { false, true })\n        {\n            cancellation.ThrowIfCancellationRequested(); var name = citizen ? \"citizen\" : \"human\";\n            var rig = await File.ReadAllTextAsync(Path.Combine(fixture.RigDirectory, citizen ? \"target_rig_sbox_citizen.json\" : \"target_rig_sbox.json\"), cancellation);\n            var target = citizen ? RetargetTargetSpec.SboxCitizen(rig) : RetargetTargetSpec.SboxDefault(rig);\n            var result = Retargeter.Convert(new RetargetRequest\n            {\n                SourceData = bytes,\n                SourceFileName = \"capture.hmotion\",\n                FootPlantCleanup = true,\n                MocapCorrections = new TargetCorrectionSettings { FirstPerson = false, StabilizeFeet = true }\n            }, target);\n            if (!result.Success) throw new Exception(\"Clip retarget failed: \" + string.Join(\"; \", result.Errors.Concat(result.Clips.Select(c => c.Error))));\n            var clip = result.Clips.Single();\n            foreach (var poses in clip.SolvedFrames) foreach (var pose in poses)\n                if (!float.IsFinite(pose.Pos.Length()) || !float.IsFinite(pose.Rot.Length())) throw new Exception(\"Non-finite target animation.\");\n            var times = Enumerable.Range(0, clip.SolvedFrames.Count).Select(i => i / (double)clip.Fps).ToArray();\n            var exported = ModelDocFbxExport.Write(target.Rig.Skeleton, motion.Name, clip.SolvedFrames, times, clip.Fps, target.UpAxis, \"WorldRelative\");\n            var roundTrip = FbxImporter.Import(exported);\n            if (roundTrip.Clips.Count != 1 || roundTrip.Clips[0].Frames.Count != clip.SolvedFrames.Count)\n                throw new Exception(\"Target FBX lost animation frames.\");\n            var path = Path.Combine(directory, name + \".fbx\"); await File.WriteAllBytesAsync(path, exported, cancellation);\n            results.Add(new { Target = name, Frames = clip.SolvedFrames.Count, Bones = target.Rig.Skeleton.Count, FbxBytes = exported.Length, Path = path });\n        }\n        return results;\n    }, cancellation);\n\n    sealed class RawFrames : ICaptureFrames, IDisposable\n    {\n        readonly FileStream stream;\n        readonly int bytes;\n        public int Width { get; }\n        public int Height { get; }\n        public int Count { get; }\n\n        internal RawFrames(Fixture fixture)\n        {\n            Width = fixture.Width; Height = fixture.Height; Count = fixture.Frames;\n            if (Width < 1 || Height < 1 || (long)Width * Height > 33_177_600) throw new ArgumentException(\"Invalid RGBA fixture dimensions.\");\n            bytes = checked(Width * Height * 4);\n            stream = new(fixture.RgbaPath, FileMode.Open, FileAccess.Read, FileShare.Read, 1024 * 1024, FileOptions.Asynchronous | FileOptions.RandomAccess);\n            if (stream.Length != (long)bytes * Count) { stream.Dispose(); throw new ArgumentException(\"RGBA fixture length does not match its declared frame count.\"); }\n        }\n\n        public async ValueTask ReadAsync(int frame, Memory<byte> rgba, CancellationToken cancellation)\n        {\n            if ((uint)frame >= (uint)Count || rgba.Length != bytes) throw new ArgumentException(\"Invalid fixture frame or destination size.\");\n            cancellation.ThrowIfCancellationRequested(); stream.Position = (long)frame * bytes;\n            await stream.ReadExactlyAsync(rgba, cancellation);\n        }\n\n        public void Dispose() => stream.Dispose();\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "dev/sam_frame_checks.cs",
            "FileName": "sam_frame_checks.cs",
            "PackageType": "library",
            "CodeKind": "Game",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System.Diagnostics;\nusing System.Text.Json;\nusing HumanoidMocapX.EditorTools;\nusing HumanoidMocapX.Inference;\nusing Sandbox;\n\nnamespace HumanoidMocapX.Checks;\n\n/// <summary>Runs released YOLOX, SAM DINOv3, body decoder and MHR on a real frame.\n/// This is an isolated body-pass diagnostic, not full video or hand refinement.</summary>\npublic static class SamFrameChecks\n{\n    /// <summary>Writes crop, keypoint and feature evidence to a JSON file. Requires\n    /// a visible person in an RGBA8 frame and installed, verified model files.</summary>\n    public static async Task<object> Run(string samPath, string mhrPath, string detectorPath, string rgbaPath,\n        int width, int height, string resultPath, CancellationToken cancellation)\n    {\n        var pixels = await File.ReadAllBytesAsync(rgbaPath, cancellation);\n        var box = await Detect(pixels, width, height, detectorPath, cancellation);\n        var shape = DinoShape.Sam(); var crop = new SamCrop(box.Left, box.Top, box.Right, box.Bottom, shape);\n        var focal = (float)Math.Sqrt((double)width * width + (double)height * height);\n        var intrinsics = new float[] { focal, 0, width / 2f, 0, focal, height / 2f, 0, 0, 1 }; var affine = new float[6]; crop.CopyAffine(affine);\n        var rgb = new float[shape.ImageElements]; var rayEncoder = new SamRays(shape); var rays = new float[rayEncoder.Elements];\n        await Task.Run(() => { crop.Prepare(pixels, width, height, rgb, cancellation); rayEncoder.Prepare(intrinsics, affine, rays, cancellation); }, cancellation);\n        var context = new float[shape.Patches * shape.Channels]; var positions = new float[context.Length];\n        var imageTimes = await Encode(samPath, shape, rgb, rays, context, positions, cancellation);\n        var model = await Task.Run(() => MhrCheckpoint.LoadBody(mhrPath, cancellation), cancellation);\n        var pose = await Task.Run(() => SamCheckpoint.LoadPoseHead(samPath, model, false, cancellation), cancellation);\n        var decoderShape = new SamDecoderShape(SamInitialTokens.Count, shape.Patches);\n        var camera = await Task.Run(() => new SamPredictionHead(VisionCheckpoint.LoadSamHead(samPath, false, cancellation), false, true), cancellation);\n        var keypoints = await Task.Run(() => new SamKeypointFeedback(VisionCheckpoint.LoadSamFeedback(samPath, false, cancellation), decoderShape, 32, 32), cancellation);\n        var projection = new SamProjection(intrinsics, affine, crop.CenterX, crop.CenterY, crop.Size, shape);\n        var feedback = new SamDecoderFeedback(decoderShape, pose, camera, keypoints); feedback.Prepare(projection, context);\n        var tokens = new float[decoderShape.TokenElements]; var tokenPositions = new float[tokens.Length]; var decoded = new float[tokens.Length];\n        await Task.Run(() => new SamInitialTokens(VisionCheckpoint.LoadSamInitialTokens(samPath, false, cancellation))\n            .Run(projection, tokens, tokenPositions, cancellation), cancellation);\n        var decoderWeights = await Task.Run(() => VisionCheckpoint.LoadSamDecoder(samPath, false, cancellation), cancellation);\n        await GameTask.MainThread(); var decoder = new SamGpuDecoder(decoderWeights, decoderShape); var timer = Stopwatch.StartNew();\n        try\n        {\n            await decoder.RunAsync(tokens, context, tokenPositions, positions, decoded, feedback.Update, cancellation);\n            await Task.Run(() => feedback.Finish(decoded, cancellation), cancellation);\n        }\n        finally { await GameTask.MainThread(); decoder.Dispose(); }\n        var decodeMilliseconds = timer.Elapsed.TotalMilliseconds;\n        var cropped = new float[140]; var depths = new float[70]; var translation = new float[3]; var imagePoints = new float[140];\n        projection.Run(pose.Keypoints, feedback.CameraParameters, cropped, depths, translation);\n        for (var i = 0; i < 70; i++)\n        {\n            imagePoints[i * 2] = ((cropped[i * 2] + .5f) * shape.Width - affine[2]) / affine[0];\n            imagePoints[i * 2 + 1] = ((cropped[i * 2 + 1] + .5f) * shape.Height - affine[5]) / affine[4];\n        }\n        var result = new\n        {\n            BodyPassOnly = true,\n            Width = width,\n            Height = height,\n            Box = box,\n            Crop = new { crop.CenterX, crop.CenterY, crop.Size },\n            ImageMilliseconds = imageTimes,\n            DecodeMilliseconds = decodeMilliseconds,\n            ImageKeypoints = imagePoints,\n            KeypointsMetres = pose.Keypoints.ToArray(),\n            Depths = depths,\n            Translation = translation,\n            BodyFeature = decoded.AsSpan(0, decoderShape.Width).ToArray(),\n            ModelParameters = pose.Model.ToArray()\n        };\n        await File.WriteAllTextAsync(resultPath, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }), cancellation);\n        return new\n        {\n            Passed = true,\n            BodyPassOnly = true,\n            Box = box,\n            Keypoints = 70,\n            BodyFeatureChannels = decoderShape.Width,\n            ImageMilliseconds = imageTimes,\n            DecodeMilliseconds = decodeMilliseconds,\n            ResultPath = resultPath\n        };\n    }\n\n    static async Task<YoloBox> Detect(byte[] pixels, int width, int height, string path, CancellationToken cancellation)\n    {\n        var network = new YoloNetwork(); var weights = await Task.Run(() => YoloCheckpoint.Load(path, network, cancellation), cancellation);\n        await GameTask.MainThread(); var detector = new YoloGpuDetector(network, weights);\n        try\n        {\n            var boxes = new YoloBox[YoloNetwork.Predictions]; var count = await detector.DetectAsync(pixels, width, height, boxes, cancellation);\n            if (count < 1) throw new Exception(\"SAM frame fixture contains no detected person.\");\n            return boxes[0];\n        }\n        finally { await GameTask.MainThread(); detector.Dispose(); }\n    }\n\n    static async Task<double[]> Encode(string path, DinoShape shape, float[] rgb, float[] rays, float[] context, float[] positions, CancellationToken cancellation)\n    {\n        var backbone = await Task.Run(() => VisionCheckpoint.LoadSamBackbone(path, cancellation), cancellation);\n        var body = await Task.Run(() => VisionCheckpoint.LoadSamImageConditioning(path, false, cancellation), cancellation);\n        var hand = await Task.Run(() => VisionCheckpoint.LoadSamImageConditioning(path, true, cancellation), cancellation);\n        await GameTask.MainThread(); var encoder = new SamGpuImageEncoder(backbone, body, hand, shape);\n        try\n        {\n            var timer = Stopwatch.StartNew(); await encoder.RunAsync(rgb, rays, context, false, cancellation);\n            var first = timer.Elapsed.TotalMilliseconds; var previous = context.ToArray();\n            await GameTask.MainThread(); timer.Restart(); await encoder.RunAsync(rgb, rays, context, false, cancellation);\n            var repeated = timer.Elapsed.TotalMilliseconds;\n            if (!previous.SequenceEqual(context)) throw new Exception(\"SAM image encoding did not repeat exactly.\");\n            encoder.CopyPositions(positions); return new[] { first, repeated };\n        }\n        finally { await GameTask.MainThread(); encoder.Dispose(); }\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "Editor/AccountBar.cs",
            "FileName": "AccountBar.cs",
            "PackageType": "library",
            "CodeKind": "Editor",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Editor;\nusing Sandbox;\n\nnamespace HumanoidMocapX.EditorTools;\n\n/// <summary>The strip across the top of the X window. With a provider: avatar, name, status pills,\n/// account ID and limits, then icon buttons for the queue, adding videos and sign-out. On a processing\n/// machine: its SSH address. On this computer: the GPU. Before setup: a pointer to settings. Missing\n/// names and pictures show as not provided; account details and setup live in Mocap adjustments \u203a Processing.</summary>\nsealed class AccountBar : Widget\n{\n    readonly HostingSettings settings;\n    readonly QueueTracker queue;\n    readonly AccountAvatar avatar;\n    readonly Label name, details, problem;\n    readonly Layout pills;\n    readonly Button signIn;\n    readonly BadgeButton queueButton;\n    readonly IconButton add, signOut;\n    CancellationTokenSource pending;\n\n    /// <summary>Provider mode when <paramref name=\"queue\"/> is set, otherwise the processing machine\n    /// or this computer, or a pointer to settings while processing is not <paramref name=\"configured\"/>.</summary>\n    internal AccountBar(Widget parent, HostingSettings settings, SshSettings machine, QueueTracker queue, bool configured, Action openSetup) : base(parent)\n    {\n        this.settings = settings; this.queue = queue;\n        Layout = Layout.Row(); Layout.Margin = new Sandbox.UI.Margin(12, 10, 12, 10); Layout.Spacing = 10;\n        avatar = Layout.Add(new AccountAvatar(this, 34));\n        var text = Layout.AddColumn(1); text.Spacing = 2;\n        var top = text.AddRow(); top.Spacing = 8;\n        name = top.Add(Ui.Bold(new Label(\"\", this), 14));\n        pills = top.AddRow(); pills.Spacing = 6;\n        top.AddStretchCell();\n        details = text.Add(Ui.Muted(new Label(\"\", this), small: true));\n        problem = Layout.Add(Ui.Error(this));\n        if (!configured)\n        {\n            avatar.ShowIcon(\"settings\");\n            name.Text = \"Not set up\";\n            details.Text = \"Choose where videos are processed: settings (top right) \u203a Processing \u203a Setup.\";\n            return;\n        }\n        if (queue is null && machine.Enabled)\n        {\n            avatar.ShowIcon(\"dns\");\n            name.Text = \"Processing machine\";\n            details.Text = $\"{machine.Address} over SSH \u00b7 videos are copied there for processing\";\n            return;\n        }\n        if (queue is null)\n        {\n            avatar.ShowIcon(\"memory\");\n            name.Text = \"This computer\";\n            var gpu = Sandbox.Engine.SystemInfo.Gpu is { Length: > 0 } gpuName && gpuName != \"unset\" ? gpuName : \"This GPU\";\n            details.Text = $\"{gpu} \u00b7 up to {FlowVideoProcessor.LaneCapacity()} frames at once \u00b7 videos never leave this computer\";\n                return;\n        }\n        signIn = Layout.Add(Ui.Primary(\"Sign in\", \"login\", () => _ = SignInAsync(openSetup)));\n        queueButton = Layout.Add(new BadgeButton(this, \"format_list_bulleted\", OpenQueue, \"Queue: your jobs on the provider\"));\n        add = Layout.Add(Ui.Icon(this, \"playlist_add\", () => QueuePopup.AddVideos(queue), \"Add videos to the queue\"));\n        signOut = Layout.Add(Ui.Icon(this, \"logout\", () => _ = SignOutAsync(), \"Sign out\"));\n        settings.Changed += Refresh; queue.Changed += Refresh;\n        Refresh();\n    }\n\n    void OpenQueue()\n    {\n        var popup = new QueuePopup(this, queue);\n        popup.OpenAt(queueButton.ScreenRect.BottomLeft + new Vector2(queueButton.Width - popup.FixedWidth, 6));\n    }\n\n    void Refresh()\n    {\n        if (!this.IsValid()) return;\n        var profile = settings.SignedIn ? settings.Profile : null;\n        var label = EditorCookie.Get(ProcessingSetup.ProviderLabelCookie, \"\");\n        signIn.Visible = profile is null; signIn.Text = label.Length > 0 ? \"Sign in with \" + label : \"Sign in\";\n        queueButton.Visible = add.Visible = signOut.Visible = profile is not null;\n        queueButton.Count = queue.Active;\n        pills.Clear(true);\n        if (profile is null)\n        {\n            name.Text = \"Signed out\"; details.Text = Host(); avatar.ShowIcon(\"person\");\n            return;\n        }\n        var user = profile.User;\n        name.Text = Clip(user.Name ?? user.Username, 32) ?? \"Name not provided\";\n        var (status, color) = profile switch\n        {\n            { Admin: true } => (\"Admin\", Ui.Accent),\n            { CanProcess: true } => (\"Whitelisted\", Ui.Accent),\n            { InGuild: false } => (\"Join the Discord server\", Theme.Yellow),\n            _ => (\"Not whitelisted\", Theme.Red)\n        };\n        pills.Add(new Pill(this, status, color));\n        if (profile.Limits is { Priority: true }) pills.Add(new Pill(this, \"Priority\", Theme.Yellow));\n        details.Text = $\"{Clip(user.Id, 40)} \u00b7 {Host()}\" + (profile.Limits is { } limit ? \" \u00b7 \" + Describe(limit) : \"\");\n        details.ToolTip = user.Id + \": your account ID on this provider. Give it to the provider to be whitelisted. Click to copy.\";\n        avatar.ShowAccount(user.Avatar, user.Name ?? user.Username);\n    }\n\n    protected override void OnMouseClick(MouseEvent e)\n    {\n        base.OnMouseClick(e);\n        // The account ID line copies the ID, so users can send it to the provider.\n        if (e.LeftMouseButton && details.IsUnderMouse && settings.Profile?.User.Id is { } id) EditorUtility.Clipboard.Copy(id);\n    }\n\n    static string Describe(HostLimits limit)\n        => (limit.MaximumClipSeconds is { } clip ? $\"clips up to {HostedCapture.Duration((int)clip)}\" : \"clips up to the provider's limit\")\n            + $\" \u00b7 uploads up to {limit.MaximumUploadBytes / (1024 * 1024)} MiB\";\n\n    string Host()\n    {\n        try { return settings.Endpoint().Host; } catch (ArgumentException) { return \"No provider address\"; }\n    }\n\n    static string Clip(string text, int length) => text is { } value && value.Length > length ? value[..(length - 1)] + \"\u2026\" : text;\n\n    async Task SignInAsync(Action openSetup)\n    {\n        if (pending is not null) return;\n        if (ProcessingSetup.SavedProvider() is not { } provider) { openSetup(); return; }\n        using var cancellation = new CancellationTokenSource(); pending = cancellation; var token = cancellation.Token;\n        Ui.Show(problem, null); signIn.Enabled = false; signIn.Text = \"Finish in your browser\u2026\";\n        try { await ProcessingSetup.SignInAsync(settings, provider, token); }\n        catch (Exception failure) when (ProcessingSetup.IsSignInFailure(failure))\n        {\n            await EditorPipeline.SwitchToMainThread();\n            if (!token.IsCancellationRequested) Ui.Show(problem, failure is OperationCanceledException ? \"Sign-in timed out. Try again.\" : failure.Message);\n        }\n        finally\n        {\n            await EditorPipeline.SwitchToMainThread();\n            pending = null;\n            if (signIn.IsValid()) { signIn.Enabled = true; Refresh(); }\n        }\n    }\n\n    async Task SignOutAsync()\n    {\n        using var client = new HostSignIn();\n        await client.SignOutAsync(settings);\n    }\n\n    public override void OnDestroyed()\n    {\n        settings.Changed -= Refresh; pending?.Cancel();\n        if (queue is not null) queue.Changed -= Refresh;\n        base.OnDestroyed();\n    }\n\n    protected override void OnPaint()\n    {\n        Paint.SetPen(Ui.CardEdge, 1);\n        Paint.DrawLine(new Vector2(0, Height - .5f), new Vector2(Width, Height - .5f));\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "tests/test_sam_backbone.cs",
            "FileName": "test_sam_backbone.cs",
            "PackageType": "library",
            "CodeKind": "UnitTest",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using HumanoidMocapX.EditorTools;\nusing HumanoidMocapX.Inference;\n\nstatic class SamBackboneTests\n{\n    internal static void Run()\n    {\n        Dimensions(); Encoder(); Checkpoint();\n        Console.WriteLine(\"PASS: 32-layer SAM DINOv3 encoder, SwiGLU gates, per-axis positions, selective checkpoint loading and allocation-free reuse\");\n    }\n\n    static void Dimensions()\n    {\n        var shape = DinoShape.Sam();\n        MotionTests.Equal(512, shape.Width); MotionTests.Equal(512, shape.Height);\n        MotionTests.Equal(1280, shape.Channels); MotionTests.Equal(20, shape.Heads); MotionTests.Equal(32, shape.Depth);\n        MotionTests.Equal(1024, shape.Patches); MotionTests.Equal(1029, shape.Tokens);\n        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(511, 512));\n        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(channels: 1281));\n        MotionTests.Throws<ArgumentException>(() => DinoShape.Sam(heads: 3));\n        var positions = OmegaPosition.Factors(2, 3, 5, new float[] { 1 }, true);\n        // Row zero's Y coordinate is -1/2; column zero's X coordinate is -2/3.\n        MotionTests.Near(-1, positions[5 * 4], 1e-6);\n        MotionTests.Near(Math.Cos(-4 * Math.PI / 3), positions[5 * 4 + 2], 1e-6);\n    }\n\n    static void Encoder()\n    {\n        var shape = DinoShape.Sam(32, 48, 8, 2); var tensors = OmegaFixture.Sam(shape.Channels, shape.Heads);\n        var encoder = new DinoImageEncoder(new(tensors), shape); var output = new float[shape.Patches * shape.Channels];\n        var image = OmegaVisionTests.Image(shape.ImageElements, 0);\n        for (var pass = 0; pass < 2; pass++)\n        {\n            if (pass > 0) Array.Reverse(image);\n            encoder.Run(image, output);\n            var expected = OmegaVisionReference.Image(tensors, image, shape.Height, shape.Width, shape.Channels, shape.Heads, true);\n            for (var i = 0; i < output.Length; i++) MotionTests.Near(expected[i], output[i], 2e-4);\n        }\n        for (var warm = 0; warm < 3; warm++) encoder.Run(image, output);\n        var before = GC.GetAllocatedBytesForCurrentThread(); encoder.Run(image, output);\n        MotionTests.Equal(0L, GC.GetAllocatedBytesForCurrentThread() - before);\n        using var cancelled = new CancellationTokenSource(); cancelled.Cancel();\n        MotionTests.Throws<OperationCanceledException>(() => encoder.Run(image, output, cancelled.Token));\n        MotionTests.Throws<ArgumentException>(() => encoder.Run(image, image.AsSpan(0, output.Length)));\n        image[0] = 1.1f; MotionTests.Throws<ArgumentException>(() => encoder.Run(image, output));\n        image[0] = float.NaN; MotionTests.Throws<ArgumentException>(() => encoder.Run(image, output));\n        var block = new OmegaBlock(new(tensors), \"backbone.encoder.blocks.0\", 8, 2, false, true);\n        var values = new float[shape.Tokens * shape.Channels];\n        MotionTests.Throws<ArgumentException>(() => block.Run(values, new(shape.Tokens, 8), new(shape.Tokens, 8, 2, false), default));\n    }\n\n    static void Checkpoint()\n    {\n        var path = Path.Combine(Path.GetTempPath(), \"sam-backbone-\" + Guid.NewGuid().ToString(\"N\") + \".pt\");\n        try\n        {\n            var tensors = OmegaFixture.Sam(8, 2);\n            tensors.Add(\"decoder.unused\", new(\"decoder.unused\", new[] { float.NaN }, new[] { 1, 1, 1, 1, 1 }));\n            foreach (var component in new string[] { null, \"state_dict\" })\n            {\n                CheckpointFixture.Write(path, tensors, component, \"\"); var loaded = VisionCheckpoint.LoadSamBackbone(path);\n                foreach (var pair in tensors.Where(pair => pair.Key.StartsWith(\"backbone.encoder.\")))\n                    MotionTests.Check(loaded.Get(pair.Key, pair.Value.Shape).Data.AsSpan().SequenceEqual(pair.Value.Data), \"SAM backbone checkpoint changed tensor layout\");\n                _ = new DinoImageEncoder(loaded, DinoShape.Sam(16, 32, 8, 2));\n                using var cancelled = new CancellationTokenSource(); cancelled.Cancel();\n                MotionTests.Throws<OperationCanceledException>(() => VisionCheckpoint.LoadSamBackbone(path, cancelled.Token));\n                File.Delete(path);\n            }\n            tensors[\"backbone.encoder.blocks.31.mlp.w3.bias\"].Data[0] = float.NaN;\n            CheckpointFixture.Write(path, tensors, \"state_dict\", \"\");\n            MotionTests.Throws<InvalidDataException>(() => VisionCheckpoint.LoadSamBackbone(path));\n        }\n        finally { File.Delete(path); }\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "tests/test_capture_inputs.cs",
            "FileName": "test_capture_inputs.cs",
            "PackageType": "library",
            "CodeKind": "UnitTest",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using HumanoidMocapX.Inference;\n\nstatic class CaptureInputTests\n{\n    internal static void Run()\n    {\n        var person = new YoloBox(10, 20, 110, 220, .8f); var other = new YoloBox(250, 10, 290, 100, .95f);\n        var track = new PersonTrack(5); track.Add([other, person]); track.Add([person with { Left = 12, Right = 112 }, other]);\n        track.Add([]); track.Add([person with { Left = 16, Right = 116 }]); track.Add([person with { Left = 18, Right = 118 }]);\n        var span = track.Complete(); var boxes = span.Boxes;\n        MotionTests.Equal(0, span.First); MotionTests.Equal(5, span.Count); MotionTests.Check(span.Note(2, 5) is null, \"A fully visible person needs no note\");\n        for (var i = 0; i < 5; i++) { MotionTests.Equal(10f + i * 2, boxes[i * 4]); MotionTests.Equal(110f + i * 2, boxes[i * 4 + 2]); }\n        MotionTests.Throws<InvalidOperationException>(() => track.Add([person]));\n        var nobody = new PersonTrack(2); nobody.Add([]); nobody.Add([]); MotionTests.Throws<InvalidOperationException>(() => nobody.Complete());\n        var unfinished = new PersonTrack(2); unfinished.Add([person]); MotionTests.Throws<InvalidOperationException>(() => unfinished.Complete());\n        // The capture starts where the person first appears and ends at their last detection.\n        var late = new PersonTrack(6); late.Add([]); late.Add([]); late.Add([person]); late.Add([]); late.Add([person with { Left = 14, Right = 114 }]); late.Add([]);\n        var visible = late.Complete();\n        MotionTests.Equal(2, visible.First); MotionTests.Equal(3, visible.Count); MotionTests.Equal(12, visible.Boxes.Length);\n        MotionTests.Equal(12f, visible.Boxes[4]); MotionTests.Equal(14f, visible.Boxes[8]); MotionTests.Near(2 / 30d, visible.StartSeconds);\n        MotionTests.Equal(\"The person is in view from 1.07 s to 1.17 s of the video, so only that part was captured.\", visible.Note(1, 6));\n        var uncertain = new PersonTrack(2); uncertain.Add([person]);\n        MotionTests.Throws<InvalidOperationException>(() => uncertain.Add([person, person with { Left = 11, Right = 111 }]));\n        // A person lost for more than half a second ends the capture; a later return is not joined on.\n        var lost = new PersonTrack(18); lost.Add([person]); for (var i = 0; i < 15; i++) lost.Add([]);\n        lost.Add([other]); lost.Add([person]);\n        var kept = lost.Complete(); MotionTests.Equal(0, kept.First); MotionTests.Equal(1, kept.Count);\n        MotionTests.Throws<ArgumentException>(() => new PersonTrack(1).Add([person with { Left = float.NaN }]));\n        var reuse = new PersonTrack(20); var input = new[] { person }; for (var i = 0; i < 4; i++) reuse.Add(input);\n        var before = GC.GetAllocatedBytesForCurrentThread(); reuse.Add(input); MotionTests.Equal(0L, GC.GetAllocatedBytesForCurrentThread() - before);\n        var noise = new float[491 * 501]; var repeated = new float[noise.Length]; FlowNoise.Fill(noise, 0); FlowNoise.Fill(repeated, 0);\n        MotionTests.Check(noise.SequenceEqual(repeated), \"Initial noise must repeat for the same seed\");\n        var mean = noise.Average(v => (double)v); var variance = noise.Average(v => (double)v * v) - mean * mean;\n        MotionTests.Near(0, mean, .01); MotionTests.Near(1, variance, .02);\n        MotionTests.Check(noise.Min() < -3 && noise.Max() > 3 && noise.All(float.IsFinite), \"Normal noise must cover both tails and remain finite\");\n        FlowNoise.Fill(repeated, 1); MotionTests.Check(!noise.SequenceEqual(repeated), \"Different seeds must vary initial noise\");\n        using var stop = new CancellationTokenSource(); stop.Cancel();\n        MotionTests.Throws<OperationCanceledException>(() => FlowNoise.Fill(noise, 0, stop.Token));\n        MotionTests.Throws<ArgumentException>(() => FlowNoise.Fill(new float[490], 0));\n        Console.WriteLine(\"PASS: person identity continuity, short-gap interpolation, ambiguous/lost-person rejection, allocation-free tracking and seeded standard-normal latents\");\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "tests/test_ccd_ik.cs",
            "FileName": "test_ccd_ik.cs",
            "PackageType": "library",
            "CodeKind": "UnitTest",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System.Numerics;\nusing HumanoidMocapX.Core.Cleanup;\nusing HumanoidMocapX.Core.Maths;\nusing HumanoidMocapX.Core.Skeleton;\n\nstatic class CcdIkTests\n{\n    internal static void Run()\n    {\n        var skeleton = Skeleton.Create(new[]\n        {\n            new BoneDefinition(\"root\", null, XForm.Identity),\n            new BoneDefinition(\"elbow\", \"root\", new XForm(Vector3.UnitX, Quaternion.Identity)),\n            new BoneDefinition(\"hand\", \"elbow\", new XForm(Vector3.UnitY, Quaternion.Identity)),\n            new BoneDefinition(\"finger\", \"hand\", new XForm(Vector3.UnitY * .2f, Quaternion.CreateFromAxisAngle(Vector3.UnitX, .4f)))\n        });\n        var rest = skeleton.Bones.Select(b => b.RestLocal).ToArray();\n        var solver = new CcdIk(skeleton, new[] { 0, 1 }, 2);\n        var pose = (XForm[])rest.Clone();\n        var residual = solver.Solve(pose, new Vector3(.7f, 1.3f, .4f), iterations: 128, tolerance: 1e-5f);\n        MotionTests.Check(residual < 1e-4, $\"CCD must reach a reachable target; residual {residual}\");\n        Invariants(rest, pose);\n        pose = (XForm[])rest.Clone();\n        residual = solver.Solve(pose, new Vector3(20, 0, 0), iterations: 128);\n        MotionTests.Near(18, residual, .001);\n        Invariants(rest, pose);\n\n        var locked = (XForm[])rest.Clone();\n        var limits = new LockedJoint(rest);\n        solver.Solve(locked, new Vector3(-1, 1, 0), constrain: limits.Apply);\n        MotionTests.Near(0, MathQ.AngleBetween(rest[0].Rot, locked[0].Rot), 1e-6);\n        MotionTests.Check(limits.Calls > 0, \"CCD must enforce the supplied joint constraint\");\n\n        var offsetSolver = new CcdIk(skeleton, new[] { 0 }, 2);\n        var offset = new Vector3(.1f, .3f, 0);\n        var offsetGoal = Vector3.Transform(new Vector3(1, 1, 0) + offset,\n            Quaternion.CreateFromAxisAngle(Vector3.UnitZ, .4f));\n        pose = (XForm[])rest.Clone();\n        MotionTests.Check(offsetSolver.Solve(pose, offsetGoal, tipOffset: offset) < .001f, \"CCD tip offset must reach the target\");\n\n        Reject(() => new CcdIk(skeleton, new[] { 1, 0 }, 2));\n        Reject(() => new CcdIk(skeleton, new[] { -1 }, 2));\n        Reject(() => solver.Solve(rest, new Vector3(float.NaN, 0, 0)));\n        Reject(() => solver.Solve(rest, Vector3.Zero, iterations: 0));\n        Reject(() => solver.Solve(rest, Vector3.Zero, gain: float.NaN));\n        var invalid = (XForm[])rest.Clone(); invalid[1].Rot = default;\n        Reject(() => solver.Solve(invalid, Vector3.Zero));\n\n        pose = (XForm[])rest.Clone();\n        for (var i = 0; i < 10; i++) solver.Solve(pose, new Vector3(.7f, 1.3f, .4f));\n        var before = GC.GetAllocatedBytesForCurrentThread();\n        for (var i = 0; i < 100; i++) solver.Solve(pose, new Vector3(.7f, 1.3f, .4f));\n        MotionTests.Check(GC.GetAllocatedBytesForCurrentThread() == before, \"CCD solve must not allocate\");\n        Console.WriteLine(\"PASS: DigitalRune CCD adaptation, reach residuals, constraints, offsets, validation and zero-allocation solve\");\n    }\n\n    static void Invariants(XForm[] before, XForm[] after)\n    {\n        for (var i = 0; i < before.Length; i++) MotionTests.Near(0, Vector3.Distance(before[i].Pos, after[i].Pos));\n        for (var i = 2; i < before.Length; i++) MotionTests.Near(0, MathQ.AngleBetween(before[i].Rot, after[i].Rot));\n    }\n\n    static void Reject(Action action)\n    {\n        try { action(); } catch (ArgumentException) { return; }\n        throw new Exception(\"CCD accepted an invalid chain or input\");\n    }\n\n    sealed class LockedJoint(XForm[] reference)\n    {\n        internal int Calls;\n        internal void Apply(XForm[] pose, int bone) { Calls++; if (bone == 0) pose[bone].Rot = reference[bone].Rot; }\n    }\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "Editor/Server/EditorHost.cs",
            "FileName": "EditorHost.cs",
            "PackageType": "library",
            "CodeKind": "Editor",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "using System;\nusing System.IO;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Editor;\nusing HumanoidMocapX.EditorTools.Video;\nusing HumanoidMocapX;\nusing HumanoidMocapX.EditorTools;\nusing Sandbox;\n\nnamespace HumanoidMocapHost;\n\n/// <summary>Opt-in processing host inside the s&amp;box editor. Operator configuration\n/// comes from MOCAP_* environment variables; see docs/editor-host.md.</summary>\npublic static class EditorHost\n{\n    // The engine exposes static console/event entry points; session state stays here.\n    static readonly SemaphoreSlim Changes = new(1, 1);\n    static EditorHostLifetime active;\n    static CancellationTokenSource starting;\n\n    /// <summary>Verifies installed Base/Latest weights, then listens on loopback. Requires\n    /// Windows Media Foundation and a GPU budget. Startup failures propagate to the console.</summary>\n    [ConCmd(\"mocap_x_host_start\", ConVarFlags.Protected, Help = \"Start the configured in-editor Humanoid Mocap X processing host\")]\n    public static async Task StartAsync()\n    {\n        await Changes.WaitAsync();\n        using var cancellation = new CancellationTokenSource();\n        starting = cancellation;\n        try\n        {\n            if (active is { IsRunning: true }) { Log.Info(\"Humanoid Mocap X host is already running.\"); return; }\n            if (active is not null) { await active.StopAsync(); active = null; }\n            if (LocalCapture.Availability is { } reason) throw new PlatformNotSupportedException(reason);\n            var config = HostConfiguration.Read(Environment.GetEnvironmentVariable,\n                Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), \"HumanoidMocapX\"));\n            await ModelStore.InstalledAsync(config.Models, FlowModel.Base, message => Log.Info(message), cancellation.Token);\n            await ModelStore.InstalledAsync(config.Models, FlowModel.Latest, message => Log.Info(message), cancellation.Token);\n            await GameTask.MainThread(); cancellation.Token.ThrowIfCancellationRequested();\n            if (!Graphics.IsAvailable || Graphics.VideoMemoryBudget == 0 && Sandbox.Engine.SystemInfo.GpuMemory == 0)\n                throw new InvalidOperationException(\"The host needs an initialized GPU with a reported video-memory budget.\");\n            active = Start(config);\n            Log.Info($\"Humanoid Mocap X host listening on http://127.0.0.1:{config.Port}/. Stop with mocap_x_host_stop.\");\n        }\n        finally { starting = null; Changes.Release(); }\n    }\n\n    static EditorHostLifetime Start(HostConfiguration config)\n    {\n        var lanes = config.Lanes == CaptureLanes.Auto ? CaptureLanes.Maximum : config.Lanes;\n        var admission = new GpuAdmission(lanes);\n        admission.Update(Graphics.VideoMemoryBudget, Graphics.VideoMemoryUsed, Sandbox.Engine.SystemInfo.GpuMemory);\n        var storage = new FileJobStorage(config.Data);\n        try\n        {\n            var processor = new CaptureProcessor(storage.CaptureDirectory, config.UploadBytes,\n                (selected, workspace, progress) => new LocalCapture(new CaptureOptions\n                { Model = selected.Model, CameraInterval = selected.CameraInterval, Lanes = lanes }, config.Models, workspace, progress),\n                ReadDurationAsync);\n            var queue = new CaptureQueue(storage, processor, TimeProvider.System, config.ActivePerOwner,\n                maximumUploadBytes: config.UploadBytes, maximumClipSeconds: config.ClipSeconds,\n                concurrentJobs: config.ConcurrentJobs, canStartJob: admission.CanStart);\n            var session = new HostSession($\"http://127.0.0.1:{config.Port}/\", config.Keys, storage, queue, ReportError);\n            return new EditorHostLifetime(session, admission);\n        }\n        catch { storage.Dispose(); throw; }\n    }\n\n    static Task<double> ReadDurationAsync(string video, CancellationToken token) => Task.Run(() =>\n    {\n        token.ThrowIfCancellationRequested();\n        using var decoder = IVideoDecoder.Open(video);\n        return decoder.Duration;\n    }, token);\n\n    /// <summary>Cancels startup, uploads and active captures, then waits for GPU cleanup.\n    /// Repeated calls are safe; completed job IDs are invalidated by the next start.</summary>\n    [ConCmd(\"mocap_x_host_stop\", ConVarFlags.Protected, Help = \"Stop and drain the in-editor Humanoid Mocap X processing host\")]\n    public static async Task StopAsync()\n    {\n        try { starting?.Cancel(); } catch (ObjectDisposedException) { } // Startup just finished.\n        await Changes.WaitAsync();\n        try\n        {\n            await GameTask.MainThread();\n            if (active is not null) { await active.StopAsync(); active = null; }\n        }\n        finally { Changes.Release(); }\n    }\n\n    [EditorEvent.Hotload]\n    static void Hotloaded() => _ = StopAfterHotloadAsync();\n\n    static async Task StopAfterHotloadAsync()\n    {\n        try { await StopAsync(); }\n        catch (Exception error) { ReportError(error); }\n    }\n\n    static void ReportError(Exception error) => Log.Error($\"Humanoid Mocap X host: {error}\");\n}\n"
        },
        {
            "Ident": "notpointless.chomnr_humanoid_mocap_x",
            "Path": "Editor/Server/HostSession.cs",
            "FileName": "HostSession.cs",
            "PackageType": "library",
            "CodeKind": "Editor",
            "AssetVersionId": 439808,
            "IsPrivate": false,
            "Code": "#nullable enable annotations\n\nusing System;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace HumanoidMocapHost;\n\n/// <summary>Owns one HTTP listener, queue loop and file-store lifetime. Shutdown drains\n/// uploads and GPU captures before disposing their resources.</summary>\ninternal sealed class HostSession : IAsyncDisposable\n{\n    readonly object gate = new();\n    readonly CancellationTokenSource stopping = new();\n    readonly FileJobStorage storage;\n    readonly CaptureQueue queue;\n    readonly HttpHost http;\n    readonly Task worker;\n    readonly Action<Exception> reportError;\n    Task? shutdown;\n    internal bool IsStopping { get { lock (gate) return shutdown is not null; } }\n\n    internal HostSession(string prefix, ApiKeys keys, FileJobStorage storage, CaptureQueue queue, Action<Exception> reportError)\n    {\n        this.storage = storage; this.queue = queue; this.reportError = reportError;\n        try { http = new HttpHost(prefix, keys, queue, reportError); }\n        catch { stopping.Dispose(); queue.Dispose(); storage.Dispose(); throw; }\n        worker = Task.Run(() => QueueLoop.RunAsync(queue, (id, error) => reportError(new InvalidOperationException($\"Capture {id} failed.\", error)), stopping.Token));\n        _ = ObserveAsync();\n    }\n\n    async Task ObserveAsync()\n    {\n        try { await worker; }\n        catch (Exception error) { reportError(error); }\n        finally\n        {\n            try { await StopAsync(); }\n            catch (Exception error) { reportError(error); }\n        }\n    }\n\n    /// <summary>Idempotently stops this instance. The returned task completes only after\n    /// cancellation and resource cleanup; callers must await it before starting a replacement.</summary>\n    internal Task StopAsync()\n    {\n        lock (gate) return shutdown ??= StopCoreAsync();\n    }\n\n    async Task StopCoreAsync()\n    {\n        await stopping.CancelAsync();\n        try { await http.DisposeAsync(); }\n        finally\n        {\n            try { await worker; }\n            finally\n            {\n                try { queue.Dispose(); }\n                finally\n                {\n                    try { storage.DeleteRun(); }\n                    finally { storage.Dispose(); stopping.Dispose(); }\n                }\n            }\n        }\n    }\n\n    public ValueTask DisposeAsync() => new(StopAsync());\n}\n"
        }
    ]
}