mirror of
https://github.com/BlackMATov/unity-flash-tools.git
synced 2025-12-17 06:29:20 +07:00
188 lines
6.5 KiB
C#
188 lines
6.5 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
|
|
using FlashTools.Internal.SwfTools;
|
|
using FlashTools.Internal.SwfTools.SwfTags;
|
|
using FlashTools.Internal.SwfTools.SwfTypes;
|
|
|
|
namespace FlashTools.Internal {
|
|
public class SwfPostprocessor : AssetPostprocessor {
|
|
static void OnPostprocessAllAssets(
|
|
string[] imported_assets, string[] deleted_assets,
|
|
string[] moved_assets, string[] moved_from_asset_paths)
|
|
{
|
|
var swf_asset_paths = imported_assets
|
|
.Where(p => Path.GetExtension(p).ToLower().Equals(".swf"));
|
|
foreach ( var swf_asset_path in swf_asset_paths ) {
|
|
SwfAssetProcess(swf_asset_path);
|
|
}
|
|
}
|
|
|
|
static void SwfAssetProcess(string swf_asset) {
|
|
var new_asset_path = Path.ChangeExtension(swf_asset, ".asset");
|
|
var new_asset = AssetDatabase.LoadAssetAtPath<SwfAnimationAsset>(new_asset_path);
|
|
if ( !new_asset ) {
|
|
new_asset = ScriptableObject.CreateInstance<SwfAnimationAsset>();
|
|
AssetDatabase.CreateAsset(new_asset, new_asset_path);
|
|
}
|
|
if ( LoadDataFromSwfFile(swf_asset, new_asset) ) {
|
|
EditorUtility.SetDirty(new_asset);
|
|
AssetDatabase.SaveAssets();
|
|
} else {
|
|
AssetDatabase.DeleteAsset(new_asset_path);
|
|
}
|
|
}
|
|
|
|
static bool LoadDataFromSwfFile(string swf_asset, SwfAnimationAsset asset) {
|
|
try {
|
|
asset.Data = LoadAnimationDataFromSwfDecoder(
|
|
swf_asset,
|
|
asset,
|
|
new SwfDecoder(swf_asset));
|
|
return true;
|
|
} catch ( Exception e ) {
|
|
Debug.LogErrorFormat("Parsing swf error: {0}", e.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static SwfAnimationData LoadAnimationDataFromSwfDecoder(
|
|
string swf_asset, SwfAnimationAsset asset, SwfDecoder decoder)
|
|
{
|
|
var animation_data = new SwfAnimationData{
|
|
FrameRate = decoder.UncompressedHeader.FrameRate
|
|
};
|
|
var context = new SwfContext();
|
|
var executer = new SwfContextExecuter(context, 0);
|
|
while ( executer.NextFrame(decoder.Tags, context.DisplayList) ) {
|
|
animation_data.Frames.Add(
|
|
LoadAnimationFrameFromContext(context));
|
|
}
|
|
animation_data.Bitmaps = LoadBitmapsFromContext(swf_asset, asset, context);
|
|
return animation_data;
|
|
}
|
|
|
|
static SwfAnimationFrameData LoadAnimationFrameFromContext(SwfContext context) {
|
|
var frame = new SwfAnimationFrameData();
|
|
frame.Name = context.DisplayList.FrameName;
|
|
return AddDisplayListToFrame(
|
|
context,
|
|
context.DisplayList,
|
|
0,
|
|
0,
|
|
Matrix4x4.identity,
|
|
SwfAnimationColorTransform.identity,
|
|
frame);
|
|
}
|
|
|
|
static SwfAnimationFrameData AddDisplayListToFrame(
|
|
SwfContext ctx,
|
|
SwfDisplayList dl,
|
|
ushort parent_depth,
|
|
ushort parent_clip_depth,
|
|
Matrix4x4 parent_matrix,
|
|
SwfAnimationColorTransform parent_color_transform,
|
|
SwfAnimationFrameData frame)
|
|
{
|
|
var instances = dl.Instances.Values
|
|
.Where(p => p.Visible);
|
|
foreach ( var inst in instances ) {
|
|
switch ( inst.Type ) {
|
|
case SwfDisplayInstanceType.Shape:
|
|
var shape_def = ctx.Library.FindDefine<SwfLibraryShapeDefine>(inst.Id);
|
|
if ( shape_def != null ) {
|
|
for ( var i = 0; i < shape_def.Bitmaps.Length; ++i ) {
|
|
var bitmap_id = shape_def.Bitmaps[i];
|
|
var bitmap_matrix = i < shape_def.Matrices.Length ? shape_def.Matrices[i] : SwfMatrix.identity;
|
|
var bitmap_def = ctx.Library.FindDefine<SwfLibraryBitmapDefine>(bitmap_id);
|
|
if ( bitmap_def != null ) {
|
|
var global_depth = (parent_depth + inst.Depth);
|
|
var local_clip_depth = (parent_clip_depth != 0 ? parent_clip_depth : inst.ClipDepth);
|
|
var global_clip_depth = (parent_clip_depth != 0 ? parent_clip_depth : (local_clip_depth != 0 ? (global_depth + local_clip_depth - 1) : 0));
|
|
|
|
Debug.LogFormat("--- Depth: {0}, ClipDepth: {1}", global_depth, global_clip_depth);
|
|
|
|
frame.Instances.Add(new SwfAnimationInstanceData{
|
|
Depth = (ushort)global_depth,
|
|
ClipDepth = (ushort)global_clip_depth,
|
|
Bitmap = bitmap_id,
|
|
Matrix = parent_matrix * inst.Matrix.ToUnityMatrix() * bitmap_matrix.ToUnityMatrix(),
|
|
ColorTransform = parent_color_transform * inst.ColorTransform.ToAnimationColorTransform()});
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case SwfDisplayInstanceType.Sprite:
|
|
var sprite_def = ctx.Library.FindDefine<SwfLibrarySpriteDefine>(inst.Id);
|
|
if ( sprite_def != null ) {
|
|
var sprite_inst = inst as SwfDisplaySpriteInstance;
|
|
AddDisplayListToFrame(
|
|
ctx,
|
|
sprite_inst.DisplayList,
|
|
(ushort)(parent_depth + sprite_inst.Depth - 1),
|
|
(ushort)(parent_clip_depth != 0 ? parent_clip_depth : sprite_inst.ClipDepth),
|
|
parent_matrix * sprite_inst.Matrix.ToUnityMatrix(),
|
|
parent_color_transform * sprite_inst.ColorTransform.ToAnimationColorTransform(),
|
|
frame);
|
|
}
|
|
break;
|
|
default:
|
|
throw new UnityException(string.Format(
|
|
"Unsupported SwfDisplayInstanceType: {0}", inst.Type));
|
|
}
|
|
}
|
|
return frame;
|
|
}
|
|
|
|
static List<SwfAnimationBitmapData> LoadBitmapsFromContext(
|
|
string swf_asset, SwfAnimationAsset asset, SwfContext context)
|
|
{
|
|
var bitmap_defines = context.Library.Defines
|
|
.Where (p => p.Value.Type == SwfLibraryDefineType.Bitmap)
|
|
.Select (p => new KeyValuePair<int, SwfLibraryBitmapDefine>(p.Key, p.Value as SwfLibraryBitmapDefine))
|
|
.ToArray();
|
|
|
|
var textures = bitmap_defines
|
|
.Select(p => LoadTextureFromBitmapDefine(p.Value));
|
|
|
|
var atlas = new Texture2D(0, 0);
|
|
var atlas_rects = atlas.PackTextures(
|
|
textures.ToArray(), asset.AtlasPadding, asset.MaxAtlasSize);
|
|
File.WriteAllBytes(
|
|
GetAtlasPath(swf_asset),
|
|
atlas.EncodeToPNG());
|
|
GameObject.DestroyImmediate(atlas, true);
|
|
AssetDatabase.ImportAsset(
|
|
GetAtlasPath(swf_asset),
|
|
ImportAssetOptions.ForceUncompressedImport);
|
|
|
|
var bitmaps = new List<SwfAnimationBitmapData>();
|
|
for ( var i = 0; i < bitmap_defines.Length; ++i ) {
|
|
var bitmap_define = bitmap_defines[i];
|
|
var bitmap_data = new SwfAnimationBitmapData{
|
|
Id = bitmap_define.Key,
|
|
RealSize = new Vector2(bitmap_define.Value.Width, bitmap_define.Value.Height),
|
|
SourceRect = atlas_rects[i]
|
|
};
|
|
bitmaps.Add(bitmap_data);
|
|
}
|
|
return bitmaps;
|
|
}
|
|
|
|
static Texture2D LoadTextureFromBitmapDefine(SwfLibraryBitmapDefine bitmap) {
|
|
var texture = new Texture2D(
|
|
bitmap.Width, bitmap.Height,
|
|
TextureFormat.ARGB32, false);
|
|
texture.LoadRawTextureData(bitmap.ARGB32);
|
|
return texture;
|
|
}
|
|
|
|
static string GetAtlasPath(string swf_asset) {
|
|
return Path.ChangeExtension(swf_asset, ".png");
|
|
}
|
|
}
|
|
} |