public void Bake(Dictionary <string, Channel> channels, List <Bone> bones, Dictionary <string, Bone> bonesByName)
    {
        int index        = bones.Count;
        var centerPoint  = ChannelTriplet.Lookup(channels, Name + "?center_point");
        var endPoint     = ChannelTriplet.Lookup(channels, Name + "?end_point");
        var orientation  = ChannelTriplet.Lookup(channels, Name + "?orientation");
        var rotation     = ChannelTriplet.Lookup(channels, Name + "?rotation");
        var translation  = ChannelTriplet.Lookup(channels, Name + "?translation");
        var scale        = ChannelTriplet.Lookup(channels, Name + "?scale");
        var generalScale = channels[Name + "?scale/general"];

        Bone parent = Parent != null ? bonesByName[Parent] : null;
        Bone bone   = new Bone(
            Name,
            index,
            parent,
            global::RotationOrder.FromString(RotationOrder),
            InheritsScale,
            centerPoint,
            endPoint,
            orientation,
            rotation,
            translation,
            scale,
            generalScale);

        bones.Add(bone);
        bonesByName.Add(Name, bone);
    }
    public Bone(string name, int index, Bone parent, RotationOrder rotationOrder, bool inheritsScale, ChannelTriplet centerPoint, ChannelTriplet endPoint, ChannelTriplet orientation, ChannelTriplet rotation, ChannelTriplet translation, ChannelTriplet scale, Channel generalScale)
    {
        if (parent == null)
        {
            if (index != 0)
            {
                throw new InvalidOperationException("root bone must be first");
            }
        }
        else if (parent.Index > index)
        {
            throw new ArgumentException("parent bones must have lower index");
        }

        Name          = name;
        Index         = index;
        Parent        = parent;
        RotationOrder = rotationOrder;
        InheritsScale = inheritsScale;
        CenterPoint   = centerPoint;
        EndPoint      = endPoint;
        Orientation   = orientation;
        Rotation      = rotation;
        Translation   = translation;
        Scale         = scale;
        GeneralScale  = generalScale;

        rotation.ExtractMinMax(out Vector3 minDegrees, out Vector3 maxDegrees);
        Vector3 minRadians = MathExtensions.DegreesToRadians(minDegrees);
        Vector3 maxRadians = MathExtensions.DegreesToRadians(maxDegrees);

        RotationConstraint = TwistSwingConstraint.MakeFromRadians(rotationOrder.TwistAxis, minRadians, maxRadians);
    }