Utility that prepares a point-cloud input for the MagicArticulate pipeline. It samples a RigMesh into an 8192-point surface cloud with normals, scales points to a ±0.9995 range, computes bounding extents and returns a Prepared record containing points, normals and denormalization transforms.
using AutoRig.Dl.UniRig;
using AutoRig.Mesh;
namespace AutoRig.Dl.MagicArticulate;
using Vector3 = System.Numerics.Vector3;
/// <summary>
/// MagicArticulate's input pipeline (demo.py Dataset): an 8192-point surface
/// cloud with normals, normalized so the max |coordinate| is 0.9995
/// (normalize_to_unit_cube), plus the residual bounds transform the reference
/// uses to denormalize predicted joints. The reference optionally rebuilds the
/// surface with marching cubes first — we sample the raw mesh (documented
/// deviation; the corpus gate validates the outcome).
/// </summary>
public static class MagicArticulateInput
{
public const int NumSamples = 8192;
public const float ScaleFactor = 0.9995f;
public sealed class Prepared
{
public required Vector3[] Points; // in ±0.9995
public required Vector3[] Normals;
/// <summary>Undo: world = (p * PcScale + PcCenter) / Scale + Center.</summary>
public required Vector3 Center; // normalize_to_unit_cube trans
public required float Scale; // normalize_to_unit_cube scale (multiplicative)
public required Vector3 PcCenter; // residual bounds of the normalized cloud
public required float PcScale;
}
public static Prepared Prepare( RigMesh mesh )
{
ArgumentNullException.ThrowIfNull( mesh );
// Pure surface sampling (vertexSamples 0) in [-1,1], then × 0.9995 —
// identical to normalize_to_unit_cube's max-|coord| convention.
var (points, normals, center, halfExtent) =
UniRigInput.SampleCloud( mesh, NumSamples, vertexSamples: 0 );
for ( var i = 0; i < points.Length; i++ )
points[i] *= ScaleFactor;
var min = points[0];
var max = points[0];
foreach ( var p in points )
{
min = Vector3.Min( min, p );
max = Vector3.Max( max, p );
}
var extent = max - min;
return new Prepared
{
Points = points,
Normals = normals,
Center = center,
Scale = ScaleFactor / halfExtent,
PcCenter = (min + max) * 0.5f,
PcScale = MathF.Max( extent.X, MathF.Max( extent.Y, extent.Z ) ) + 1e-5f,
};
}
}