static List <SwfClipAsset.Sequence> LoadClipSequences(
            SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
        {
            var sequences = new List <SwfClipAsset.Sequence>();

            if (IsValidAssetsForFrame(asset, symbol))
            {
                foreach (var frame in symbol.Frames)
                {
                    var baked_frame = BakeClipFrame(asset, data, frame);
                    if (!string.IsNullOrEmpty(frame.Anchor) &&
                        (sequences.Count < 1 || sequences.Last().Name != frame.Anchor))
                    {
                        sequences.Add(new SwfClipAsset.Sequence {
                            Name = frame.Anchor
                        });
                    }
                    else if (sequences.Count < 1)
                    {
                        sequences.Add(new SwfClipAsset.Sequence {
                            Name = "Default"
                        });
                    }
                    sequences.Last().Frames.Add(baked_frame);
                }
            }
            return(sequences);
        }
        // ---------------------------------------------------------------------
        //
        // ConfigureBitmaps
        //
        // ---------------------------------------------------------------------

        static SwfAssetData ConfigureBitmaps(SwfAsset asset, SwfAssetData data)
        {
            var textures = new List <KeyValuePair <ushort, Texture2D> >(data.Bitmaps.Count);

            for (var i = 0; i < data.Bitmaps.Count; ++i)
            {
                _progressBar.UpdateProgress(
                    "configure bitmaps",
                    (float)(i + 1) / data.Bitmaps.Count);
                var bitmap = data.Bitmaps[i];
                if (bitmap.Redirect == 0)
                {
                    textures.Add(new KeyValuePair <ushort, Texture2D>(
                                     bitmap.Id,
                                     LoadTextureFromData(bitmap, asset.Settings)));
                }
            }
            var rects = PackAndSaveBitmapsAtlas(
                GetAtlasPath(asset),
                textures.Select(p => p.Value).ToArray(),
                asset.Settings);

            for (var i = 0; i < data.Bitmaps.Count; ++i)
            {
                var bitmap      = data.Bitmaps[i];
                var texture_key = bitmap.Redirect > 0 ? bitmap.Redirect : bitmap.Id;
                bitmap.SourceRect = SwfRectData.FromURect(
                    rects[textures.FindIndex(p => p.Key == texture_key)]);
            }
            return(data);
        }
        // ---------------------------------------------------------------------
        //
        // ConfigureClips
        //
        // ---------------------------------------------------------------------

        static SwfAssetData ConfigureClips(SwfAsset asset, SwfAssetData data)
        {
            for (var i = 0; i < data.Symbols.Count; ++i)
            {
                _progressBar.UpdateProgress(
                    "configure clips",
                    (float)(i + 1) / data.Symbols.Count);
                ConfigureClip(asset, data, data.Symbols[i]);
            }
            return(data);
        }
 static SwfBitmapData FindBitmapFromAssetData(SwfAssetData data, int bitmap_id)
 {
     for (var i = 0; i < data.Bitmaps.Count; ++i)
     {
         var bitmap = data.Bitmaps[i];
         if (bitmap.Id == bitmap_id)
         {
             return(bitmap);
         }
     }
     return(null);
 }
        static void ConfigureClipAsset(
            SwfClipAsset clip_asset, SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
        {
            var asset_guid  = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(asset));
            var asset_atlas = AssetDatabase.LoadAssetAtPath <Sprite>(AssetDatabase.GetAssetPath(asset.Atlas));

            clip_asset.Name      = symbol.Name;
            clip_asset.Sprite    = asset_atlas;
            clip_asset.FrameRate = data.FrameRate;
            clip_asset.AssetGUID = asset_guid;
            clip_asset.Sequences = LoadClipSequences(asset, data, symbol);
            EditorUtility.SetDirty(clip_asset);
        }
        static void ConfigureClip(SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
        {
            var asset_guid  = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(asset));
            var clip_assets = SwfEditorUtils.LoadAllAssetsDBByFilter <SwfClipAsset>("t:SwfClipAsset")
                              .Where(p => p.AssetGUID == asset_guid && p.Name == symbol.Name);

            if (clip_assets.Any())
            {
                foreach (var clip_asset in clip_assets)
                {
                    ConfigureClipAsset(clip_asset, asset, data, symbol);
                }
            }
            else
            {
                var asset_path      = AssetDatabase.GetAssetPath(asset);
                var clip_asset_path = Path.ChangeExtension(asset_path, symbol.Name + ".asset");
                SwfEditorUtils.LoadOrCreateAsset <SwfClipAsset>(clip_asset_path, (new_clip_asset, created) => {
                    ConfigureClipAsset(new_clip_asset, asset, data, symbol);
                    return(true);
                });
            }
        }
        static SwfClipAsset.Frame BakeClipFrame(
            SwfAsset asset, SwfAssetData data, SwfFrameData frame)
        {
            List <uint>       baked_uvs       = new List <uint>();
            List <uint>       baked_mulcolors = new List <uint>();
            List <uint>       baked_addcolors = new List <uint>();
            List <Vector2>    baked_vertices  = new List <Vector2>();
            List <BakedGroup> baked_groups    = new List <BakedGroup>();
            List <Material>   baked_materials = new List <Material>();

            foreach (var inst in frame.Instances)
            {
                var bitmap = inst != null
                                        ? FindBitmapFromAssetData(data, inst.Bitmap)
                                        : null;

                while (bitmap != null && bitmap.Redirect > 0)
                {
                    bitmap = FindBitmapFromAssetData(data, bitmap.Redirect);
                }
                if (bitmap != null)
                {
                    var br = asset.Settings.BitmapTrimming
                                                ? bitmap.TrimmedRect
                                                : new SwfRectIntData(bitmap.RealWidth, bitmap.RealHeight);

                    var v0 = new Vector2(br.xMin, br.yMin);
                    var v1 = new Vector2(br.xMax, br.yMin);
                    var v2 = new Vector2(br.xMax, br.yMax);
                    var v3 = new Vector2(br.xMin, br.yMax);

                    var matrix =
                        Matrix4x4.Scale(new Vector3(1.0f, -1.0f, 1.0f) / asset.Settings.PixelsPerUnit) *
                        inst.Matrix.ToUMatrix() *
                        Matrix4x4.Scale(new Vector3(1.0f / 20.0f, 1.0f / 20.0f, 1.0f));

                    baked_vertices.Add(matrix.MultiplyPoint3x4(v0));
                    baked_vertices.Add(matrix.MultiplyPoint3x4(v1));
                    baked_vertices.Add(matrix.MultiplyPoint3x4(v2));
                    baked_vertices.Add(matrix.MultiplyPoint3x4(v3));

                    var source_rect = bitmap.SourceRect;
                    baked_uvs.Add(SwfEditorUtils.PackUV(source_rect.xMin, source_rect.yMin));
                    baked_uvs.Add(SwfEditorUtils.PackUV(source_rect.xMax, source_rect.yMax));

                    uint mul_pack0, mul_pack1;
                    SwfEditorUtils.PackFColorToUInts(
                        inst.ColorTrans.mulColor.ToUVector4(),
                        out mul_pack0, out mul_pack1);
                    baked_mulcolors.Add(mul_pack0);
                    baked_mulcolors.Add(mul_pack1);

                    uint add_pack0, add_pack1;
                    SwfEditorUtils.PackFColorToUInts(
                        inst.ColorTrans.addColor.ToUVector4(),
                        out add_pack0, out add_pack1);
                    baked_addcolors.Add(add_pack0);
                    baked_addcolors.Add(add_pack1);

                    if (baked_groups.Count == 0 ||
                        baked_groups[baked_groups.Count - 1].Type != inst.Type ||
                        baked_groups[baked_groups.Count - 1].BlendMode != inst.BlendMode.type ||
                        baked_groups[baked_groups.Count - 1].ClipDepth != inst.ClipDepth)
                    {
                        baked_groups.Add(new BakedGroup {
                            Type          = inst.Type,
                            BlendMode     = inst.BlendMode.type,
                            ClipDepth     = inst.ClipDepth,
                            StartVertex   = baked_vertices.Count - 4,
                            TriangleCount = 0,
                            Material      = null
                        });
                    }

                    baked_groups.Last().TriangleCount += 6;
                }
            }

            for (var i = 0; i < baked_groups.Count; ++i)
            {
                var group = baked_groups[i];
                switch (group.Type)
                {
                case SwfInstanceData.Types.Mask:
                    group.Material = SwfMaterialCache.GetIncrMaskMaterial();
                    break;

                case SwfInstanceData.Types.Group:
                    group.Material = SwfMaterialCache.GetSimpleMaterial(group.BlendMode);
                    break;

                case SwfInstanceData.Types.Masked:
                    group.Material = SwfMaterialCache.GetMaskedMaterial(group.BlendMode, group.ClipDepth);
                    break;

                case SwfInstanceData.Types.MaskReset:
                    group.Material = SwfMaterialCache.GetDecrMaskMaterial();
                    break;

                default:
                    throw new UnityException(string.Format(
                                                 "SwfAssetPostprocessor. Incorrect instance type: {0}",
                                                 group.Type));
                }
                if (group.Material)
                {
                    baked_materials.Add(group.Material);
                }
                else
                {
                    throw new UnityException(string.Format(
                                                 "SwfAssetPostprocessor. Material for baked group ({0}) not found",
                                                 group.Type));
                }
            }

            var mesh_data = new SwfClipAsset.MeshData {
                SubMeshes = baked_groups
                            .Select(p => new SwfClipAsset.SubMeshData {
                    StartVertex = p.StartVertex,
                    IndexCount  = p.TriangleCount
                })
                            .ToArray(),
                Vertices  = baked_vertices.ToArray(),
                UVs       = baked_uvs.ToArray(),
                AddColors = baked_addcolors.ToArray(),
                MulColors = baked_mulcolors.ToArray()
            };

            return(new SwfClipAsset.Frame(
                       frame.Labels.ToArray(),
                       mesh_data,
                       baked_materials.ToArray()));
        }