public static BoneKeyframe AssembleBones(StudioMdlWriter meshBuilder, BasePart rootPart) { Rbx2Source.Print("Building Skeleton..."); BoneKeyframe kf = new BoneKeyframe(); List <Bone> bones = kf.Bones; List <Node> nodes = meshBuilder.Nodes; Bone rootBone = new Bone(rootPart.Name, rootPart); rootBone.C0 = new CFrame(); rootBone.IsAvatarBone = true; bones.Add(rootBone); Node rootNode = rootBone.Node; rootNode.NodeIndex = 0; nodes.Add(rootNode); // Assemble the base rig. BoneAssemblePrep prep = new BoneAssemblePrep(ref bones, ref nodes); GenerateBones(prep, rootPart.GetChildrenOfClass <Attachment>()); // Assemble the accessories. prep.AllowNonRigs = true; GenerateBones(prep, prep.NonRigs.ToArray()); // Apply the rig cframe data. ApplyBoneCFrames(rootPart); meshBuilder.Skeleton.Add(kf); return(kf); }
private static void GenerateBones(BoneAssemblePrep prep, Attachment[] queue) { if (queue.Length == 0) { return; } Instance bin = queue[0].Parent.Parent; foreach (Attachment a0 in queue) { List <Attachment> a1s = FindOtherAttachments(a0, bin); foreach (Attachment a1 in a1s) { if (a1 != null && !prep.Completed.Contains(a1)) { BasePart part0 = (BasePart)a0.Parent; BasePart part1 = (BasePart)a1.Parent; bool isRigAttachment = a0.Name.EndsWith("RigAttachment", StringComparison.InvariantCulture); if (isRigAttachment || prep.AllowNonRigs) { StudioBone bone = new StudioBone(part1.Name, part0, part1) { C0 = a0.CFrame, C1 = a1.CFrame, }; bone.IsAvatarBone = !prep.AllowNonRigs; prep.Bones.Add(bone); Node node = bone.Node; node.NodeIndex = prep.Bones.IndexOf(bone); prep.Nodes.Add(node); if (!prep.Completed.Contains(a0)) { prep.Completed.Add(a0); } prep.Completed.Add(a1); if (!prep.AllowNonRigs) { GenerateBones(prep, part1.GetChildrenOfType <Attachment>()); } } else // We'll deal with Accessory attachments afterwards. { prep.NonRigs.Add(a0); } } } } }