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); }
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); }