public TextureCompositor ComposeTextureMap(Folder characterAssets, WebBodyColors bodyColors)
        {
            Contract.Requires(characterAssets != null && bodyColors != null);

            var compositor = new TextureCompositor(AvatarType.R6, RECT_FULL)
            {
                CharacterAssets = characterAssets
            };

            // Append BodyColors
            compositor.AppendColor(bodyColors.TorsoColorId, COMPOSIT_TORSO, RECT_FULL);
            compositor.AppendColor(bodyColors.LeftArmColorId, COMPOSIT_LEFT_ARM, RECT_FULL);
            compositor.AppendColor(bodyColors.LeftLegColorId, COMPOSIT_LEFT_LEG, RECT_FULL);
            compositor.AppendColor(bodyColors.RightArmColorId, COMPOSIT_RIGHT_ARM, RECT_FULL);
            compositor.AppendColor(bodyColors.RightLegColorId, COMPOSIT_RIGHT_LEG, RECT_FULL);

            // Append Head & Face
            Asset faceAsset = GetAvatarFace(characterAssets);

            compositor.AppendTexture(faceAsset, RECT_HEAD, 1);
            compositor.AppendColor(bodyColors.HeadColorId, RECT_HEAD);

            // Append Shirt
            Shirt shirt = characterAssets.FindFirstChildOfClass <Shirt>();

            if (shirt != null)
            {
                Asset shirtAsset = Asset.GetByAssetId(shirt.ShirtTemplate);
                compositor.AppendTexture(shirtAsset, COMPOSIT_SHIRT, RECT_FULL, 2);
            }

            // Append Pants
            Pants pants = characterAssets.FindFirstChildOfClass <Pants>();

            if (pants != null)
            {
                Asset pantsAsset = Asset.GetByAssetId(pants.PantsTemplate);
                compositor.AppendTexture(pantsAsset, COMPOSIT_PANTS, RECT_FULL, 1);
            }

            // Append T-Shirt
            ShirtGraphic tshirt = characterAssets.FindFirstChildOfClass <ShirtGraphic>();

            if (tshirt != null)
            {
                Asset tshirtAsset = Asset.GetByAssetId(tshirt.Graphic);
                compositor.AppendTexture(tshirtAsset, RECT_TSHIRT, 3, RotateFlipType.Rotate90FlipNone);
            }

            return(compositor);
        }
        public TextureBindings BindTextures(TextureCompositor compositor, Dictionary <string, ValveMaterial> materials)
        {
            Contract.Requires(compositor != null && materials != null);
            TextureBindings textures = new TextureBindings();

            Bitmap core = compositor.BakeTextureMap();

            Rbx2Source.SetDebugImage(core);

            Bitmap head = TextureCompositor.CropBitmap(core, RECT_HEAD);

            textures.BindTexture("Head", head);

            Bitmap body            = TextureCompositor.CropBitmap(core, RECT_BODY);
            Folder characterAssets = compositor.CharacterAssets;

            Rbx2Source.Print("Processing Package Textures...");
            Rbx2Source.IncrementStack();

            // Collect CharacterMeshes
            var packagedLimbs = characterAssets
                                .GetChildrenOfType <CharacterMesh>()
                                .ToDictionary(mesh => mesh.BodyPart);

            // Compose the textures that will be used
            var limbOverlays = new Dictionary <BodyPart, long>();
            var limbBitmaps  = new Dictionary <long, Bitmap>()
            {
                { 0, body }
            };

            foreach (BodyPart limb in LimbMatcher.Keys)
            {
                // Head is already textured, ignore it.
                if (limb == BodyPart.Head)
                {
                    continue;
                }

                // Is there a CharacterMesh for this limb?
                if (packagedLimbs.ContainsKey(limb))
                {
                    // Check the CharacterMesh textures.
                    CharacterMesh mesh = packagedLimbs[limb];

                    if (mesh.OverlayTextureId > 0)
                    {
                        // Use the overlay texture for this limb.
                        long overlayId = mesh.OverlayTextureId;
                        limbOverlays.Add(limb, overlayId);

                        // Compose this overlay texture with the body texture if it doesn't exist yet.
                        if (!limbBitmaps.ContainsKey(overlayId))
                        {
                            Asset overlayAsset = Asset.Get(overlayId);

                            TextureCompositor overlayCompositor = new TextureCompositor(AvatarType.R6, RECT_FULL);
                            overlayCompositor.SetContext("Overlay Texture " + overlayId);
                            overlayCompositor.AppendTexture(overlayAsset, RECT_BODY, 1);
                            overlayCompositor.AppendTexture(body, RECT_BODY);

                            Bitmap overlayTex = overlayCompositor.BakeTextureMap(RECT_BODY);
                            limbBitmaps.Add(overlayId, overlayTex);
                        }

                        continue;
                    }
                    else if (mesh.BaseTextureId > 0)
                    {
                        // Use the base texture for this limb.
                        long baseId = mesh.BaseTextureId;
                        limbOverlays.Add(limb, baseId);

                        // Compose the base texture if it doesn't exist yet.
                        if (!limbBitmaps.ContainsKey(baseId))
                        {
                            Asset baseAsset = Asset.Get(baseId);

                            TextureCompositor baseCompositor = new TextureCompositor(AvatarType.R6, RECT_FULL);
                            baseCompositor.SetContext("Base Texture " + baseId);
                            baseCompositor.AppendTexture(baseAsset, RECT_BODY);

                            Bitmap baseTex = baseCompositor.BakeTextureMap(RECT_BODY);
                            limbBitmaps.Add(baseId, baseTex);
                        }

                        continue;
                    }
                }

                // If no continue statement is reached, fallback to using the body texture.
                // This occurs if the limb has no package, or the package limb has no textures.
                limbOverlays.Add(limb, 0);
            }

            // Add the images into the texture assembly.
            foreach (long id in limbBitmaps.Keys)
            {
                Bitmap bitmap  = limbBitmaps[id];
                string matName = GetBodyMatName(id);
                textures.BindTexture(matName, bitmap, false);
            }

            // Link the limbs to their textures.
            foreach (BodyPart limb in limbOverlays.Keys)
            {
                long   id      = limbOverlays[limb];
                string matName = GetBodyMatName(id);

                string limbName = Rbx2Source.GetEnumName(limb);
                textures.BindTextureAlias(limbName, matName);
            }

            // Handle the rest of the materials
            foreach (string matName in materials.Keys)
            {
                if (!textures.MatLinks.ContainsKey(matName))
                {
                    ValveMaterial material = materials[matName];
                    Asset         texture  = material.TextureAsset;

                    TextureCompositor matComp = new TextureCompositor(AvatarType.R6, RECT_ITEM);
                    matComp.SetContext("Accessory Texture " + matName);
                    matComp.AppendTexture(texture, RECT_ITEM);

                    Bitmap bitmap = matComp.BakeTextureMap();
                    textures.BindTexture(matName, bitmap);
                }
            }

            Rbx2Source.DecrementStack();
            return(textures);
        }
        public TextureCompositor ComposeTextureMap(Folder characterAssets, BodyColors bodyColors)
        {
            TextureCompositor compositor = new TextureCompositor(AvatarType.R15, 1024, 568);

            // Append BodyColors
            compositor.AppendColor(bodyColors.HeadColor, RECT_HEAD);
            compositor.AppendColor(bodyColors.TorsoColor, RECT_TORSO);
            compositor.AppendColor(bodyColors.LeftArmColor, RECT_LEFT_ARM);
            compositor.AppendColor(bodyColors.LeftLegColor, RECT_LEFT_LEG);
            compositor.AppendColor(bodyColors.RightArmColor, RECT_RIGHT_ARM);
            compositor.AppendColor(bodyColors.RightLegColor, RECT_RIGHT_LEG);

            // Append Face
            Asset face = GetAvatarFace(characterAssets);

            compositor.AppendTexture(face, RECT_HEAD, 1);

            // Append Shirt
            Shirt shirt = characterAssets.FindFirstChildOfClass <Shirt>();

            if (shirt != null)
            {
                Asset shirtTemplate = Asset.GetByAssetId(shirt.ShirtTemplate);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_TORSO, RECT_TORSO, 2);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_LEFT_LIMB, RECT_LEFT_ARM, 1);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_RIGHT_LIMB, RECT_RIGHT_ARM, 1);
            }

            // Append Pants
            Pants pants = characterAssets.FindFirstChildOfClass <Pants>();

            if (pants != null)
            {
                Asset pantsTemplate = Asset.GetByAssetId(pants.PantsTemplate);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_TORSO, RECT_TORSO, 1);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_LEFT_LIMB, RECT_LEFT_LEG, 1);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_RIGHT_LIMB, RECT_RIGHT_LEG, 1);
            }

            // Append T-Shirt
            ShirtGraphic tshirt = characterAssets.FindFirstChildOfClass <ShirtGraphic>();

            if (tshirt != null)
            {
                Asset graphic = Asset.GetByAssetId(tshirt.Graphic);
                compositor.AppendTexture(graphic, RECT_TSHIRT, 4);
            }

            // Append Package Overlays
            Folder      avatarParts   = characterAssets.FindFirstChild <Folder>("ASSEMBLY");
            List <Limb> overlainLimbs = new List <Limb>();

            foreach (MeshPart part in avatarParts.GetChildrenOfClass <MeshPart>())
            {
                Limb   limb      = GetLimb(part);
                string textureId = part.TextureID;
                if (textureId != null && textureId.Length > 0 && !overlainLimbs.Contains(limb))
                {
                    Asset overlay = Asset.GetByAssetId(textureId);

                    if (limb == Limb.Torso)
                    {
                        compositor.AppendTexture(overlay, RECT_TORSO, 3);
                    }
                    else if (limb == Limb.LeftArm)
                    {
                        compositor.AppendTexture(overlay, RECT_LEFT_ARM, 3);
                    }
                    else if (limb == Limb.RightArm)
                    {
                        compositor.AppendTexture(overlay, RECT_RIGHT_ARM, 3);
                    }
                    else if (limb == Limb.LeftLeg)
                    {
                        compositor.AppendTexture(overlay, RECT_LEFT_LEG, 3);
                    }
                    else if (limb == Limb.RightLeg)
                    {
                        compositor.AppendTexture(overlay, RECT_RIGHT_LEG, 3);
                    }

                    overlainLimbs.Add(limb);
                }
            }

            return(compositor);
        }
Example #4
0
        public TextureCompositor ComposeTextureMap(Folder characterAssets, WebBodyColors bodyColors)
        {
            Contract.Requires(characterAssets != null && bodyColors != null);
            TextureCompositor compositor = new TextureCompositor(AvatarType.R15, 1024, 568);

            // Append BodyColors
            compositor.AppendColor(bodyColors.HeadColorId, RECT_HEAD);
            compositor.AppendColor(bodyColors.TorsoColorId, RECT_TORSO);
            compositor.AppendColor(bodyColors.LeftArmColorId, RECT_LEFT_ARM);
            compositor.AppendColor(bodyColors.LeftLegColorId, RECT_LEFT_LEG);
            compositor.AppendColor(bodyColors.RightArmColorId, RECT_RIGHT_ARM);
            compositor.AppendColor(bodyColors.RightLegColorId, RECT_RIGHT_LEG);

            // Append Face
            Asset face = GetAvatarFace(characterAssets);

            compositor.AppendTexture(face, RECT_HEAD, 1);

            // Append Shirt
            Shirt shirt = characterAssets.FindFirstChildOfClass <Shirt>();

            if (shirt != null)
            {
                Asset shirtTemplate = Asset.GetByAssetId(shirt.ShirtTemplate);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_TORSO, RECT_TORSO, 2);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_LEFT_LIMB, RECT_LEFT_ARM, 1);
                compositor.AppendTexture(shirtTemplate, COMPOSIT_RIGHT_LIMB, RECT_RIGHT_ARM, 1);
            }

            // Append Pants
            Pants pants = characterAssets.FindFirstChildOfClass <Pants>();

            if (pants != null)
            {
                Asset pantsTemplate = Asset.GetByAssetId(pants.PantsTemplate);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_TORSO, RECT_TORSO, 1);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_LEFT_LIMB, RECT_LEFT_LEG, 1);
                compositor.AppendTexture(pantsTemplate, COMPOSIT_RIGHT_LIMB, RECT_RIGHT_LEG, 1);
            }

            // Append T-Shirt
            ShirtGraphic tshirt = characterAssets.FindFirstChildOfClass <ShirtGraphic>();

            if (tshirt != null)
            {
                Asset graphic = Asset.GetByAssetId(tshirt.Graphic);
                compositor.AppendTexture(graphic, RECT_TSHIRT, 4);
            }

            // Append Package Overlays
            Folder          avatarParts   = characterAssets.FindFirstChild <Folder>("ASSEMBLY");
            List <BodyPart> overlainLimbs = new List <BodyPart>();

            foreach (MeshPart part in avatarParts.GetChildrenOfType <MeshPart>())
            {
                BodyPart?maybeLimb = GetLimb(part);

                if (!maybeLimb.HasValue)
                {
                    continue;
                }

                BodyPart limb      = maybeLimb.Value;
                string   textureId = part.TextureID;

                if (textureId != null && textureId.Length > 0 && !overlainLimbs.Contains(limb))
                {
                    Asset     overlay = Asset.GetByAssetId(textureId);
                    Rectangle crop    = UVCrops[limb];
                    compositor.AppendTexture(overlay, crop, 3);
                    overlainLimbs.Add(limb);
                }
            }

            return(compositor);
        }