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);
        }
Example #2
0
        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));
 }
Example #7
0
        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);
        }