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