Exemple #1
0
        public TextureBindings BindTextures(TextureCompositor compositor, Dictionary <string, ValveMaterial> materials)
        {
            Contract.Requires(compositor != null && materials != null);
            TextureBindings textureBinds = new TextureBindings();

            Bitmap uvMap = compositor.BakeTextureMap();

            Rbx2Source.SetDebugImage(uvMap);

            foreach (string matName in materials.Keys)
            {
                Rbx2Source.Print("Building Material {0}", matName);
                ValveMaterial material = materials[matName];
                Image         image    = null;

                if (material.UseAvatarMap)
                {
                    if (Enum.TryParse(matName, out BodyPart limb))
                    {
                        Rectangle cropRegion = UVCrops[limb];
                        image = TextureCompositor.CropBitmap(uvMap, cropRegion);
                    }
                }
                else
                {
                    Asset texture = material.TextureAsset;

                    if (texture != null)
                    {
                        byte[]       textureData   = texture.GetContent();
                        MemoryStream textureStream = new MemoryStream(textureData);

                        image = Image.FromStream(textureStream);
                        textureStream.Dispose();
                    }
                }

                textureBinds.BindTexture(matName, image);
            }

            return(textureBinds);
        }
        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 TextureAssembly AssembleTextures(TextureCompositor compositor, Dictionary <string, Material> materials)
        {
            TextureAssembly assembly = new TextureAssembly();

            assembly.Images   = new Dictionary <string, Image>();
            assembly.MatLinks = new Dictionary <string, string>();

            Bitmap uvMap = compositor.BakeTextureMap();

            Rbx2Source.SetDebugImage(uvMap);

            ImageAttributes blankAtt = new ImageAttributes();

            foreach (string materialName in materials.Keys)
            {
                Rbx2Source.Print("Building Material {0}", materialName);
                Material material = materials[materialName];
                Image    image    = null;
                if (material.UseAvatarMap)
                {
                    Limb limb;
                    if (Enum.TryParse(materialName, out limb))
                    {
                        Rectangle cropRegion = UVCrops[limb];

                        Size size = cropRegion.Size;
                        int  w    = size.Width;
                        int  h    = size.Height;

                        Point origin = cropRegion.Location;
                        int   x      = origin.X;
                        int   y      = origin.Y;

                        Bitmap    newImg   = new Bitmap(w, h);
                        Graphics  graphics = Graphics.FromImage(newImg);
                        Rectangle dest     = new Rectangle(Point.Empty, size);

                        graphics.DrawImage(uvMap, dest, x, y, w, h, GraphicsUnit.Pixel, blankAtt);
                        graphics.Dispose();

                        image = newImg;
                    }
                }
                else
                {
                    Asset texture = material.TextureAsset;
                    if (texture != null)
                    {
                        byte[]       textureData   = texture.GetContent();
                        MemoryStream textureStream = new MemoryStream(textureData);
                        image = Image.FromStream(textureStream);
                    }
                }
                if (image != null)
                {
                    assembly.Images.Add(materialName, image);
                    assembly.MatLinks.Add(materialName, materialName);
                }
                else
                {
                    Rbx2Source.Print("Missing Image for Material {0}?", materialName);
                }
            }

            return(assembly);
        }
Exemple #4
0
        public Bitmap BakeTextureMap()
        {
            var bitmap = new Bitmap(canvas.Width, canvas.Height);

            layers.Sort();

            composed = 0;

            Rbx2Source.Print("Composing " + context + "...");
            Rbx2Source.IncrementStack();

            foreach (CompositData composit in layers)
            {
                var buffer    = Graphics.FromImage(bitmap);
                var drawFlags = composit.DrawFlags;
                var canvas    = composit.Rect;

                if (drawFlags.HasFlag(DrawFlags.Rect))
                {
                    if (drawFlags.HasFlag(DrawFlags.Color))
                    {
                        composit.UseBrush(brush => buffer.FillRectangle(brush, canvas));
                    }
                    else if (drawFlags.HasFlag(DrawFlags.Texture))
                    {
                        Bitmap image = composit.GetTextureBitmap();

                        if (composit.FlipMode > 0)
                        {
                            image.RotateFlip(composit.FlipMode);
                        }

                        buffer.DrawImage(image, canvas);
                    }
                }
                else if (drawFlags.HasFlag(DrawFlags.Guide))
                {
                    Mesh guide = composit.Guide;

                    for (int face = 0; face < guide.NumFaces; face++)
                    {
                        Vertex[] verts  = composit.GetGuideVerts(face);
                        Point    offset = canvas.Location;

                        Point[] poly = verts
                                       .Select(vert => vert.ToPoint(canvas, offset))
                                       .ToArray();

                        if (drawFlags.HasFlag(DrawFlags.Color))
                        {
                            composit.UseBrush(brush => buffer.FillPolygon(brush, poly));
                        }
                        else if (drawFlags.HasFlag(DrawFlags.Texture))
                        {
                            Bitmap    texture = composit.GetTextureBitmap();
                            Rectangle bbox    = GetBoundingBox(poly);

                            Point  origin    = bbox.Location;
                            Bitmap drawLayer = new Bitmap(bbox.Width, bbox.Height);

                            Point[] uv = verts
                                         .Select(vert => vert.ToUV(texture))
                                         .ToArray();

                            int origin_X = origin.X,
                                origin_Y = origin.Y;

                            for (int x = bbox.Left; x < bbox.Right; x++)
                            {
                                for (int y = bbox.Top; y < bbox.Bottom; y++)
                                {
                                    var pixel   = new Point(x, y);
                                    var bcPoint = new BarycentricPoint(pixel, poly);

                                    if (bcPoint.InBounds())
                                    {
                                        var   uvPixel = bcPoint.ToCartesian(uv);
                                        Color color   = texture.GetPixel(uvPixel.X, uvPixel.Y);
                                        drawLayer.SetPixel(x - origin_X, y - origin_Y, color);
                                    }
                                }
                            }

                            buffer.DrawImage(drawLayer, origin);
                            drawLayer.Dispose();
                        }
                    }
                }

                Rbx2Source.Print("{0}/{1} layers composed...", ++composed, layers.Count);

                if (layers.Count > 2)
                {
                    Rbx2Source.SetDebugImage(bitmap);
                }

                buffer.Dispose();
            }

            Rbx2Source.Print("Done!");
            Rbx2Source.DecrementStack();

            return(bitmap);
        }
        public Bitmap BakeTextureMap()
        {
            Bitmap bitmap = new Bitmap(canvas.Width, canvas.Height);

            layers.Sort();

            composed = 0;

            Rbx2Source.Print("Composing " + context + "...");
            Rbx2Source.IncrementStack();

            foreach (CompositData composit in layers)
            {
                Graphics buffer = Graphics.FromImage(bitmap);

                DrawMode drawMode = composit.DrawMode;
                DrawType drawType = composit.DrawType;

                Rectangle compositCanvas = composit.Rect;

                if (drawMode == DrawMode.Rect)
                {
                    if (drawType == DrawType.Color)
                    {
                        using (Brush brush = new SolidBrush(composit.DrawColor))
                            buffer.FillRectangle(brush, compositCanvas);
                    }
                    else if (drawType == DrawType.Texture)
                    {
                        Bitmap image = composit.GetTextureBitmap();
                        if (composit.FlipMode > 0)
                        {
                            image.RotateFlip(composit.FlipMode);
                        }

                        buffer.DrawImage(image, compositCanvas);
                    }
                }
                else if (drawMode == DrawMode.Guide)
                {
                    Mesh guide = composit.Guide;

                    for (int face = 0; face < guide.FaceCount; face++)
                    {
                        Vertex[] verts  = composit.GetGuideVerts(face);
                        Point    offset = compositCanvas.Location;

                        Point vert_a = CompositUtil.VertexToPoint(verts[0], compositCanvas, offset);
                        Point vert_b = CompositUtil.VertexToPoint(verts[1], compositCanvas, offset);
                        Point vert_c = CompositUtil.VertexToPoint(verts[2], compositCanvas, offset);

                        Point[] polygon = new Point[3] {
                            vert_a, vert_b, vert_c
                        };

                        if (drawType == DrawType.Color)
                        {
                            using (Brush brush = new SolidBrush(composit.DrawColor))
                                buffer.FillPolygon(brush, polygon);
                        }
                        else if (drawType == DrawType.Texture)
                        {
                            Bitmap    texture = composit.GetTextureBitmap();
                            Rectangle bbox    = CompositUtil.GetBoundingBox(vert_a, vert_b, vert_c);

                            Point origin = bbox.Location;
                            int   width  = bbox.Width;
                            int   height = bbox.Height;

                            Bitmap drawLayer = new Bitmap(width, height);

                            Point uv_a = CompositUtil.VertexToUV(verts[0], texture);
                            Point uv_b = CompositUtil.VertexToUV(verts[1], texture);
                            Point uv_c = CompositUtil.VertexToUV(verts[2], texture);

                            for (int x = bbox.Left; x < bbox.Right; x++)
                            {
                                for (int y = bbox.Top; y < bbox.Bottom; y++)
                                {
                                    Point            pixel   = new Point(x, y);
                                    BarycentricPoint bcPixel = CompositUtil.ToBarycentric(pixel, vert_a, vert_b, vert_c);

                                    if (CompositUtil.InTriangle(bcPixel))
                                    {
                                        Point uvPixel = CompositUtil.ToCartesian(bcPixel, uv_a, uv_b, uv_c);
                                        Color color   = texture.GetPixel(uvPixel.X, uvPixel.Y);
                                        drawLayer.SetPixel(x - origin.X, y - origin.Y, color);
                                    }
                                }
                            }

                            buffer.DrawImage(drawLayer, origin);
                            drawLayer.Dispose();
                        }
                    }
                }

                Rbx2Source.Print("{0}/{1} layers composed...", ++composed, layers.Count);

                if (layers.Count > 2)
                {
                    Rbx2Source.SetDebugImage(bitmap);
                }

                buffer.Dispose();
            }

            Rbx2Source.Print("Done!");
            Rbx2Source.DecrementStack();

            return(bitmap);
        }