示例#1
0
        public bool Import(TR2CombinedLevel level, TextureLevelMapping mapping)
        {
            // Ensure any changes already made are committed to the level
            mapping.CommitGraphics();

            using (TexturePacker packer = new TexturePacker(level.Data))
            {
                List <TRObjectTexture> textures = level.Data.ObjectTextures.ToList();
                foreach (StaticTextureSource source in mapping.LandmarkMapping.Keys)
                {
                    if (textures.Count == _maxTextures)
                    {
                        break;
                    }

                    if (!source.HasVariants)
                    {
                        continue;
                    }

                    List <Rectangle> segments = source.VariantMap[source.Variants[0]];
                    foreach (int segmentIndex in mapping.LandmarkMapping[source].Keys)
                    {
                        foreach (LandmarkTextureTarget target in mapping.LandmarkMapping[source][segmentIndex])
                        {
                            IndexedTRObjectTexture texture = CreateTexture(segments[segmentIndex]);
                            target.MappedTextureIndex = textures.Count;
                            textures.Add(texture.Texture);

                            Bitmap image;
                            if (target.BackgroundIndex != -1)
                            {
                                IndexedTRObjectTexture indexedTexture = new IndexedTRObjectTexture
                                {
                                    Index   = target.BackgroundIndex,
                                    Texture = level.Data.ObjectTextures[target.BackgroundIndex]
                                };
                                BitmapGraphics tile = GetTile(level.Data, indexedTexture.Atlas);

                                BitmapGraphics clip = new BitmapGraphics(tile.Extract(indexedTexture.Bounds));
                                clip.Overlay(source.Bitmap);
                                image = clip.Bitmap;
                            }
                            else
                            {
                                image = source.Bitmap;
                            }

                            packer.AddRectangle(new TexturedTileSegment(texture, image));
                        }
                    }
                }

                try
                {
                    packer.Pack(true);

                    // Perform the room data remapping
                    foreach (StaticTextureSource source in mapping.LandmarkMapping.Keys)
                    {
                        if (!source.HasVariants)
                        {
                            continue;
                        }

                        foreach (int segmentIndex in mapping.LandmarkMapping[source].Keys)
                        {
                            foreach (LandmarkTextureTarget target in mapping.LandmarkMapping[source][segmentIndex])
                            {
                                if (target.MappedTextureIndex == -1)
                                {
                                    // There wasn't enough space for this
                                    continue;
                                }

                                TR2Room room = level.Data.Rooms[target.RoomNumber];
                                foreach (int rectIndex in target.RectangleIndices)
                                {
                                    room.RoomData.Rectangles[rectIndex].Texture = (ushort)target.MappedTextureIndex;
                                }
                            }
                        }
                    }

                    level.Data.ObjectTextures    = textures.ToArray();
                    level.Data.NumObjectTextures = (uint)textures.Count;

                    return(true);
                }
                catch (PackingException)
                {
                    return(false);
                }
            }
        }
示例#2
0
        private void CollateSegments()
        {
            // Rebuild the segment list. We assume the list of IndexedTRObjectTextures has been
            // ordered by area descending to preserve the "master" texture for each segment.
            _importSegments = new Dictionary <TRModelDefinition, List <TexturedTileSegment> >();

            // Track existing sprite sequences to avoid duplication
            List <TRSpriteSequence> spriteSequences = Level.SpriteSequences.ToList();

            foreach (TRModelDefinition definition in Definitions)
            {
                if (!definition.HasGraphics || definition.IsDependencyOnly)
                {
                    continue;
                }

                _importSegments[definition] = new List <TexturedTileSegment>();
                using (BitmapGraphics bg = new BitmapGraphics(definition.Bitmap))
                {
                    foreach (int segmentIndex in definition.ObjectTextures.Keys)
                    {
                        Bitmap segmentClip          = bg.Extract(definition.TextureSegments[segmentIndex]);
                        TexturedTileSegment segment = null;
                        foreach (IndexedTRObjectTexture texture in definition.ObjectTextures[segmentIndex])
                        {
                            if (segment == null)
                            {
                                _importSegments[definition].Add(segment = new TexturedTileSegment(texture, segmentClip));
                            }
                            else
                            {
                                segment.AddTexture(texture);
                            }
                        }
                    }

                    List <TR2Entities> spriteEntities = new List <TR2Entities>(definition.SpriteSequences.Keys);
                    foreach (TR2Entities spriteEntity in spriteEntities)
                    {
                        TRSpriteSequence existingSequence = spriteSequences.Find(s => s.SpriteID == (int)spriteEntity);
                        if (existingSequence != null)
                        {
                            definition.SpriteSequences.Remove(spriteEntity);
                            continue;
                        }
                        else
                        {
                            // Add it to the tracking list in case we are importing 2 or more models
                            // that share a sequence e.g. Dragon/Flamethrower and Flame_S_H
                            spriteSequences.Add(new TRSpriteSequence {
                                SpriteID = (int)spriteEntity
                            });
                        }

                        // The sequence will be merged later when we know the sprite texture offsets.
                        // For now, add the segments we need for packing.
                        Dictionary <int, List <IndexedTRSpriteTexture> > spriteTextures = definition.SpriteTextures[spriteEntity];
                        foreach (int segmentIndex in spriteTextures.Keys)
                        {
                            Bitmap segmentClip          = bg.Extract(definition.TextureSegments[segmentIndex]);
                            TexturedTileSegment segment = null;
                            foreach (IndexedTRSpriteTexture texture in spriteTextures[segmentIndex])
                            {
                                if (segment == null)
                                {
                                    _importSegments[definition].Add(segment = new TexturedTileSegment(texture, segmentClip));
                                }
                                else
                                {
                                    segment.AddTexture(texture);
                                }
                            }
                        }
                    }
                }
            }
        }