예제 #1
0
        public override void Export()
        {
            List <TexturedTileSegment> allSegments = new List <TexturedTileSegment>();

            using (TexturePacker levelPacker = new TexturePacker(Level, TextureClassifier))
            {
                Dictionary <TexturedTile, List <TexturedTileSegment> > textureSegments = levelPacker.GetModelSegments(Definition.Entity);

                TRTextureDeduplicator deduplicator = new TRTextureDeduplicator
                {
                    SegmentMap     = textureSegments,
                    UpdateGraphics = false
                };
                deduplicator.Deduplicate();

                Definition.ObjectTextures  = new Dictionary <int, List <IndexedTRObjectTexture> >();
                Definition.SpriteSequences = new Dictionary <TR2Entities, TRSpriteSequence>();
                Definition.SpriteTextures  = new Dictionary <TR2Entities, Dictionary <int, List <IndexedTRSpriteTexture> > >();

                int bitmapIndex = 0;
                foreach (List <TexturedTileSegment> segments in textureSegments.Values)
                {
                    for (int i = 0; i < segments.Count; i++)
                    {
                        TexturedTileSegment segment = segments[i];
                        if (!deduplicator.ShouldIgnoreSegment(Definition.Entity, segment))
                        {
                            allSegments.Add(segment);
                            Definition.ObjectTextures[bitmapIndex++] = new List <IndexedTRObjectTexture>(segment.Textures.Cast <IndexedTRObjectTexture>().ToArray());
                        }
                    }
                }

                if (_entitySpriteDependencies.ContainsKey(Definition.Entity))
                {
                    foreach (TR2Entities spriteEntity in _entitySpriteDependencies[Definition.Entity])
                    {
                        TRSpriteSequence sequence = Level.SpriteSequences.ToList().Find(s => s.SpriteID == (int)spriteEntity);
                        if (sequence != null)
                        {
                            Definition.SpriteSequences[spriteEntity] = sequence;
                        }

                        Dictionary <TexturedTile, List <TexturedTileSegment> > spriteSegments = levelPacker.GetSpriteSegments(spriteEntity);
                        Definition.SpriteTextures[spriteEntity] = new Dictionary <int, List <IndexedTRSpriteTexture> >();
                        foreach (List <TexturedTileSegment> segments in spriteSegments.Values)
                        {
                            for (int i = 0; i < segments.Count; i++)
                            {
                                TexturedTileSegment segment = segments[i];
                                allSegments.Add(segment);
                                Definition.SpriteTextures[spriteEntity][bitmapIndex++] = new List <IndexedTRSpriteTexture>(segment.Textures.Cast <IndexedTRSpriteTexture>().ToArray());
                            }
                        }
                    }
                }

                if (allSegments.Count > 0)
                {
                    using (TexturePacker segmentPacker = new TexturePacker())
                    {
                        segmentPacker.AddRectangles(allSegments);

                        segmentPacker.Options = new PackingOptions
                        {
                            FillMode  = PackingFillMode.Horizontal,
                            OrderMode = PackingOrderMode.Area,
                            Order     = PackingOrder.Descending,
                            GroupMode = PackingGroupMode.Squares
                        };
                        segmentPacker.TileWidth    = _defaultBitmapWidth;
                        segmentPacker.TileHeight   = _defaultBitmapHeight;
                        segmentPacker.MaximumTiles = 1;

                        segmentPacker.Pack();

                        if (segmentPacker.OrphanedRectangles.Count > 0)
                        {
                            throw new PackingException(string.Format("Failed to export textures for {0}.", Definition.Entity));
                        }

                        Definition.ObjectTextureCost = segmentPacker.TotalUsedSpace;

                        TexturedTile     tile  = segmentPacker.Tiles[0];
                        List <Rectangle> rects = new List <Rectangle>();
                        foreach (TexturedTileSegment segment in allSegments)
                        {
                            rects.Add(segment.MappedBounds);
                        }

                        Definition.TextureSegments = rects.ToArray();

                        Rectangle region = tile.GetOccupiedRegion();
                        Definition.Bitmap = tile.BitmapGraphics.Extract(region);

                        if (ExportIndividualSegments)
                        {
                            string dir = Path.Combine(SegmentsFolder, Definition.Alias.ToString());
                            if (Directory.Exists(dir))
                            {
                                Directory.Delete(dir, true);
                            }
                            Directory.CreateDirectory(dir);

                            foreach (TexturedTileSegment segment in allSegments)
                            {
                                segment.Bitmap.Save(Path.Combine(dir, segment.FirstTextureIndex + ".png"), ImageFormat.Png);
                            }
                        }
                    }
                }
                else
                {
                    Definition.ObjectTextureCost = 0;
                }
            }
        }
예제 #2
0
        private void Pack()
        {
            using (TexturePacker packer = new TexturePacker(Level))
            {
                List <TR2Entities> removals = new List <TR2Entities>();
                if (ClearUnusedSprites)
                {
                    removals.Add(TR2Entities.Map_M_U);
                }

                if (EntitiesToRemove != null)
                {
                    removals.AddRange(EntitiesToRemove);
                }
                packer.RemoveModelSegments(removals, TextureRemap);

                ApplyFlamePatch();

                if (ClearUnusedSprites)
                {
                    RemoveUnusedSprites(packer);
                }

                List <TexturedTileSegment> allSegments = new List <TexturedTileSegment>();
                foreach (List <TexturedTileSegment> segmentList in _importSegments.Values)
                {
                    // We only add unique segments, so if another segment already exists,
                    // remap the definition's segment to that one. Example of when this is
                    // needed is importing the dragon as DragonBack duplicates a lot of
                    // DragonFront, so this will greatly reduce the import cost.
                    for (int i = 0; i < segmentList.Count; i++)
                    {
                        TexturedTileSegment segment = segmentList[i];
                        int j = FindMatchingSegment(allSegments, segment);
                        if (j == -1)
                        {
                            allSegments.Add(segment);
                        }
                        else
                        {
                            TexturedTileSegment otherSegment = allSegments[j];
                            segmentList[i] = allSegments[j];
                            foreach (IndexedTRObjectTexture texture in segment.Textures)
                            {
                                if (!otherSegment.IsObjectTextureFor(texture.Index))
                                {
                                    otherSegment.AddTexture(texture);
                                }
                            }
                        }
                    }
                }

                packer.AddRectangles(allSegments);
                packer.Pack(true);

                if (packer.OrphanedRectangles.Count > 0)
                {
                    List <string> entityNames = new List <string>();
                    foreach (TRModelDefinition def in Definitions)
                    {
                        entityNames.Add(def.Entity.ToString());
                    }
                    throw new PackingException(string.Format
                                               (
                                                   "Failed to pack {0} rectangles for model types [{1}].",
                                                   packer.OrphanedRectangles.Count,
                                                   string.Join(", ", entityNames)
                                               ));
                }
            }
        }