public static Vector3 ComputeAccessoryScale(AvatarScale scale, BasePart limb, BasePart handle) { string limbScaleType = GetAvatarPartScaleType(limb); string handleScaleType = GetAvatarPartScaleType(handle); Vector3 limbScale = ComputeLimbScale(scale, limb); if (limbScaleType == handleScaleType) { return(limbScale); } // Okay so... the goal here is to figure out what the scale of this accessory would be when // the limb is at its original size, and then multiply it by the current scale of the limb. Vector3 limbR15, limbNormal, limbSlender, handleR15, handleNormal, handleSlender; SampleScales ( limb, limbScaleType, out limbR15, out limbNormal, out limbSlender ); SampleScales ( limb, handleScaleType, out handleR15, out handleNormal, out handleSlender ); Vector3 originScale; if (handleScaleType == "Normal") { originScale = handleNormal / limbNormal; } else if (handleScaleType == "Slender") { originScale = handleSlender / limbSlender; } else { originScale = handleR15 / limbR15; } return(originScale * limbScale); }
public static Vector3 ComputeLimbScale(AvatarScale avatarScale, BasePart part) { Contract.Requires(avatarScale != null && part != null); Vector3 sampleNoChange = new Vector3(1, 1, 1); string limbName = part.Name; BodyPart?limb = GetLimb(part); if (!limb.HasValue) { return(sampleNoChange); } // Compute the base scale Vector3 baseScale = new Vector3(avatarScale.Width, avatarScale.Height, avatarScale.Depth); // Determine the AvatarPartScaleType for this part. string scaleType = GetAvatarPartScaleType(part); // Select the scales we will interpolate. SampleScales ( part, scaleType, out Vector3 scaleR15, out Vector3 scaleNormal, out Vector3 scaleSlender ); // Compute the Rthro scaling based on the current proportions and body-type. Vector3 scaleProportions = scaleNormal.Lerp(scaleSlender, avatarScale.Proportion); Vector3 scaleBodyType = scaleR15.Lerp(scaleProportions, avatarScale.BodyType); Vector3 result = scaleBodyType; if (limbName == "Head") { result *= avatarScale.Head; } else { result *= baseScale; } return(result); }
public StudioMdlWriter AssembleModel(Folder characterAssets, AvatarScale scale, bool collisionModel = false) { StudioMdlWriter meshBuilder = new StudioMdlWriter(); // Build Character Folder import = RBXM.LoadFromAsset(R6AssemblyAsset); Folder assembly = import.FindFirstChild <Folder>("ASSEMBLY"); assembly.Parent = characterAssets; BasePart head = assembly.FindFirstChild <BasePart>("Head"); BasePart torso = assembly.FindFirstChild <BasePart>("Torso"); torso.CFrame = new CFrame(); foreach (Instance asset in characterAssets.GetChildren()) { if (asset.IsA("CharacterMesh") && !collisionModel) { CharacterMesh characterMesh = (CharacterMesh)asset; string limbName = LimbMatcher[characterMesh.BodyPart]; MeshPart limb = assembly.FindFirstChild <MeshPart>(limbName); if (limb != null) { limb.MeshId = "rbxassetid://" + characterMesh.MeshId; } } else if (asset.IsA("Accoutrement") && !collisionModel) { PrepareAccessory(asset, assembly); } else if (asset.IsA("DataModelMesh")) { OverwriteHead(asset, head); } } BoneKeyframe keyframe = AssembleBones(meshBuilder, torso); foreach (Bone bone in keyframe.Bones) { BuildAvatarGeometry(meshBuilder, bone); } return(meshBuilder); }
public StudioMdlWriter AssembleModel(Folder characterAssets, AvatarScale scale, bool collisionModel = false) { Contract.Requires(characterAssets != null && scale != null); StudioMdlWriter meshBuilder = new StudioMdlWriter(); // Build Character var import = R6AssemblyAsset.OpenAsModel(); Folder assembly = import.FindFirstChild <Folder>("ASSEMBLY"); assembly.Parent = characterAssets; BasePart head = assembly.FindFirstChild <BasePart>("Head"); BasePart torso = assembly.FindFirstChild <BasePart>("Torso"); torso.CFrame = new CFrame(); foreach (Instance asset in characterAssets.GetChildren()) { if (asset is CharacterMesh && !collisionModel) { var characterMesh = asset as CharacterMesh; string limbName = LimbMatcher[characterMesh.BodyPart]; var limb = assembly.FindFirstChild <MeshPart>(limbName); limb.MeshId = "rbxassetid://" + characterMesh.MeshId; } else if (asset is Accoutrement && !collisionModel) { PrepareAccessory(asset, assembly); } else if (asset is DataModelMesh) { OverwriteHead(asset as DataModelMesh, head); } } BoneKeyframe keyframe = AssembleBones(meshBuilder, torso); foreach (StudioBone bone in keyframe.Bones) { BuildAvatarGeometry(meshBuilder, bone); } return(meshBuilder); }
public StudioMdlWriter AssembleModel(Folder characterAssets, AvatarScale scale) { StudioMdlWriter meshBuilder = new StudioMdlWriter(); // Build Character Folder import = RBXM.LoadFromAsset(R15AssemblyAsset); Folder assembly = import.FindFirstChild <Folder>("ASSEMBLY"); assembly.Parent = characterAssets; Part head = assembly.FindFirstChild <Part>("Head"); Vector3 avatarScale = GetAvatarScale(scale); foreach (Instance asset in characterAssets.GetChildren()) { if (asset.IsA("Part")) { Part existing = assembly.FindFirstChild <Part>(asset.Name); if (existing != null) { existing.Destroy(); } asset.Parent = assembly; } else if (asset.IsA("Accoutrement")) { PrepareAccessory(asset, assembly); } else if (asset.IsA("DataModelMesh")) { OverwriteHead(asset, head); } } // Avatar Scaling foreach (Part part in assembly.GetChildrenOfClass <Part>()) { Limb limb = GetLimb(part); if (limb != Limb.Unknown) { part.Size *= avatarScale; foreach (Attachment attachment in part.GetChildrenOfClass <Attachment>()) { attachment.CFrame = CFrame.Scale(attachment.CFrame, avatarScale); } } } Part torso = assembly.FindFirstChild <Part>("LowerTorso"); torso.CFrame = new CFrame(); BoneKeyframe keyframe = AssembleBones(meshBuilder, torso); List <Bone> bones = keyframe.Bones; // Build File Data. Rbx2Source.Print("Building Geometry..."); Rbx2Source.IncrementStack(); foreach (Bone bone in bones) { BuildAvatarGeometry(meshBuilder, bone); } Rbx2Source.DecrementStack(); return(meshBuilder); }
public static Vector3 GetAvatarScale(AvatarScale scale) { return(new Vector3(scale.Width, scale.Height, 1)); }
public StudioMdlWriter AssembleModel(Folder characterAssets, AvatarScale scale, bool collisionModel = false) { Contract.Requires(characterAssets != null); StudioMdlWriter meshBuilder = new StudioMdlWriter(); // Build Character var import = R15AssemblyAsset.OpenAsModel(); Folder assembly = import.FindFirstChild <Folder>("ASSEMBLY"); BasePart head = assembly.FindFirstChild <BasePart>("Head"); assembly.Parent = characterAssets; foreach (Instance asset in characterAssets.GetChildren()) { if (asset is BasePart) { BasePart existing = assembly.FindFirstChild <BasePart>(asset.Name); if (existing != null) { existing.Destroy(); } asset.Parent = assembly; } else if (asset is Folder && asset.Name == "R15ArtistIntent") { foreach (BasePart child in asset.GetChildrenOfType <BasePart>()) { BasePart existing = assembly.FindFirstChild <BasePart>(child.Name); if (existing != null) { existing.Destroy(); } child.Parent = assembly; } } else if (asset is Accoutrement && !collisionModel) { PrepareAccessory(asset, assembly); } else if (asset is DataModelMesh) { OverwriteHead(asset as DataModelMesh, head); } } // Apply limb scaling var parts = assembly.GetChildrenOfType <BasePart>(); var attachMap = new Dictionary <string, Attachment>(); var avatarParts = parts.Where((part) => { var limb = GetLimb(part); return(limb.HasValue); }); var accessoryParts = parts.Except(avatarParts); foreach (BasePart avatarPart in avatarParts) { Vector3 limbScale = ComputeLimbScale(scale, avatarPart); foreach (Attachment att in avatarPart.GetChildrenOfType <Attachment>()) { attachMap[att.Name] = att; } ScalePart(avatarPart, limbScale); } // Apply accessory scaling foreach (BasePart handle in accessoryParts) { Attachment handleAtt = handle.FindFirstChildOfClass <Attachment>(); if (handleAtt != null) { string attName = handleAtt.Name; if (attachMap.ContainsKey(attName)) { Attachment avatarAtt = attachMap[attName]; BasePart avatarPart = avatarAtt.Parent as BasePart; Vector3 accessoryScale = ComputeAccessoryScale(scale, avatarPart, handle); ScalePart(handle, accessoryScale); } } } BasePart torso = assembly.FindFirstChild <BasePart>("LowerTorso"); torso.CFrame = new CFrame(); BoneKeyframe keyframe = AssembleBones(meshBuilder, torso); List <StudioBone> bones = keyframe.Bones; // Build File Data. Rbx2Source.Print("Building Geometry..."); Rbx2Source.IncrementStack(); foreach (StudioBone bone in bones) { BuildAvatarGeometry(meshBuilder, bone); } Rbx2Source.DecrementStack(); return(meshBuilder); }