public static StudioMdlWriter AssembleModel(Asset asset) { Contract.Requires(asset != null); var content = asset.OpenAsModel(); Rbx2Source.ScheduleTasks("GatherParts", "BuildMesh"); List <BasePart> parts = new List <BasePart>(); AddParts(parts, content); if (parts.Count == 0) { throw new Exception("No parts were found inside of this asset!"); } BasePart primaryPart = null; foreach (BasePart part in parts) { if (part is MeshPart || part.Name == "Handle") { primaryPart = part; break; } } if (primaryPart == null) // k lol { primaryPart = parts[0]; } primaryPart.Name = asset.ProductInfo.WindowsSafeName.Trim(); // Mark the primaryPart's location as the center. CFrame rootCoord = primaryPart.CFrame; foreach (BasePart part in parts) { part.CFrame = rootCoord.ToObjectSpace(part.CFrame); } Rbx2Source.MarkTaskCompleted("GatherParts"); Rbx2Source.PrintHeader("BUILDING MESH"); StudioMdlWriter writer = new StudioMdlWriter(); BoneKeyframe skeleton = new BoneKeyframe(); writer.Skeleton.Add(skeleton); List <StudioBone> bones = skeleton.Bones; List <Node> nodes = writer.Nodes; List <Triangle> triangles = writer.Triangles; int numAssembledParts = 0; var materials = writer.Materials; var nameCounts = new Dictionary <string, int>(); foreach (BasePart part in parts) { // Make sure this part has a unique name. string name = part.Name; if (nameCounts.ContainsKey(name)) { int count = ++nameCounts[name]; name += count.ToInvariantString(); part.Name = name; } else { nameCounts[name] = 0; } // Assemble the part. var material = new ValveMaterial(); Mesh geometry = Mesh.BakePart(part, material); if (geometry != null && geometry.NumFaces > 0) { string task = "BuildGeometry_" + name; Rbx2Source.ScheduleTasks(task); Rbx2Source.Print("Building Geometry for {0}", name); var bone = new StudioBone(name, primaryPart, part) { C0 = part.CFrame }; bones.Add(bone); Node node = bone.Node; nodes.Add(node); int faceStride; materials.Add(name, material); if (geometry.HasLODs) { faceStride = geometry.LODs[1]; } else { faceStride = geometry.NumFaces; } for (int i = 0; i < faceStride; i++) { Triangle tri = new Triangle() { Node = node, Mesh = geometry, FaceIndex = i, Material = name, }; triangles.Add(tri); } Rbx2Source.MarkTaskCompleted(task); numAssembledParts++; } } Rbx2Source.MarkTaskCompleted("BuildMesh"); return(writer); }