compress asset data

This commit is contained in:
2016-09-21 01:16:12 +07:00
parent 63fea79f49
commit 2ce9897d60
10 changed files with 198 additions and 122 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 075eada96ece147de8eeee4710c5ab0f
timeCreated: 1474360714
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -145,7 +145,7 @@ Camera:
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 5
orthographic size: 23
m_Depth: 0
m_CullingMask:
serializedVersion: 2

View File

@@ -8,8 +8,7 @@ using System.Collections.Generic;
namespace FlashTools.Internal {
[CustomEditor(typeof(SwfAsset)), CanEditMultipleObjects]
public class SwfAssetEditor : Editor {
List<SwfAsset> _assets = new List<SwfAsset>();
bool _clipsFoldout = false;
List<SwfAsset> _assets = new List<SwfAsset>();
//
//
@@ -121,38 +120,6 @@ namespace FlashTools.Internal {
}
}
void DrawGUIClips() {
var asset = _assets.Count == 1 ? _assets.First() : null;
if ( asset && asset.Clips != null && asset.Clips.Count > 0 ) {
_clipsFoldout = EditorGUILayout.Foldout(_clipsFoldout, "Clips");
if ( _clipsFoldout ) {
SwfEditorUtils.DoWithEnabledGUI(false, () => {
var clip_count = Mathf.Min(asset.Data.Symbols.Count, asset.Clips.Count);
for ( var i = 0; i < clip_count; ++i ) {
EditorGUILayout.ObjectField(
asset.Data.Symbols[i].Name,
asset.Clips[i],
typeof(SwfClipAsset),
false);
}
});
DrawGUIClipsControls();
}
}
}
void DrawGUIClipsControls() {
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
{
if ( GUILayout.Button("Reimport all") ) {
RevertAllOverriddenSettings();
ApplyAllOverriddenSettings();
}
}
GUILayout.EndHorizontal();
}
// ---------------------------------------------------------------------
//
// Messages
@@ -160,8 +127,7 @@ namespace FlashTools.Internal {
// ---------------------------------------------------------------------
void OnEnable() {
_assets = targets.OfType<SwfAsset>().ToList();
_clipsFoldout = false;
_assets = targets.OfType<SwfAsset>().ToList();
}
void OnDisable() {
@@ -172,7 +138,6 @@ namespace FlashTools.Internal {
serializedObject.Update();
DrawDefaultInspector();
DrawGUISettingsControls();
DrawGUIClips();
if ( GUI.changed ) {
serializedObject.ApplyModifiedProperties();
}

View File

@@ -27,28 +27,30 @@ namespace FlashTools.Internal {
static void SwfAssetProcess(SwfAsset asset) {
try {
if ( asset.Converting.Stage == 0 ) {
ConfigureBitmaps(asset);
var new_data = ConfigureBitmaps(
asset,
SwfEditorUtils.DecompressAsset<SwfAssetData>(asset.Data));
asset.Data = SwfEditorUtils.CompressAsset(new_data);
++asset.Converting.Stage;
EditorUtility.SetDirty(asset);
AssetDatabase.ImportAsset(
AssetDatabase.GetAssetPath(asset));
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset));
} else if ( asset.Converting.Stage == 1 ) {
asset.Atlas = LoadAssetAtlas(asset);
if ( asset.Atlas ) {
ConfigureAtlas(asset);
ConfigureClips(asset);
ConfigureClips(
asset,
SwfEditorUtils.DecompressAsset<SwfAssetData>(asset.Data));
}
++asset.Converting.Stage;
EditorUtility.SetDirty(asset);
AssetDatabase.ImportAsset(
AssetDatabase.GetAssetPath(asset));
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(asset));
}
} catch ( Exception e ) {
Debug.LogErrorFormat(
"<b>[FlashTools]</b> Postprocess swf asset error: {0}",
e.Message);
AssetDatabase.DeleteAsset(
AssetDatabase.GetAssetPath(asset));
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(asset));
} finally {
if ( asset ) {
UpdateAssetClips(asset);
@@ -76,8 +78,8 @@ namespace FlashTools.Internal {
//
// ---------------------------------------------------------------------
static void ConfigureBitmaps(SwfAsset asset) {
var textures = asset.Data.Bitmaps
static SwfAssetData ConfigureBitmaps(SwfAsset asset, SwfAssetData data) {
var textures = data.Bitmaps
.Where (p => p.Redirect == 0)
.Select (p => new KeyValuePair<ushort, Texture2D>(
p.Id,
@@ -87,11 +89,13 @@ namespace FlashTools.Internal {
GetAtlasPath(asset),
textures.Select(p => p.Value).ToArray(),
asset.Settings);
for ( var i = 0; i < asset.Data.Bitmaps.Count; ++i ) {
var bitmap = asset.Data.Bitmaps[i];
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 = rects[textures.FindIndex(p => p.Key == texture_key)];
bitmap.SourceRect = SwfRectData.FromURect(
rects[textures.FindIndex(p => p.Key == texture_key)]);
}
return data;
}
static Texture2D LoadTextureFromData(SwfBitmapData bitmap) {
@@ -99,25 +103,9 @@ namespace FlashTools.Internal {
bitmap.RealWidth, bitmap.RealHeight,
TextureFormat.ARGB32, false);
texture.LoadRawTextureData(bitmap.ARGB32);
RevertTexturePremultipliedAlpha(texture);
return texture;
}
static void RevertTexturePremultipliedAlpha(Texture2D texture) {
for ( int y = 0; y < texture.height; ++y ) {
for ( int x = 0; x < texture.width; ++x ) {
var c = texture.GetPixel(x, y);
if ( c.a > 0 ) {
c.r /= c.a;
c.g /= c.a;
c.b /= c.a;
}
texture.SetPixel(x, y, c);
}
}
texture.Apply();
}
struct BitmapsAtlasInfo {
public Texture2D Atlas;
public Rect[] Rects;
@@ -127,6 +115,7 @@ namespace FlashTools.Internal {
string atlas_path, Texture2D[] textures, SwfSettingsData settings)
{
var atlas_info = PackBitmapsAtlas(textures, settings);
RevertTexturePremultipliedAlpha(atlas_info.Atlas);
File.WriteAllBytes(atlas_path, atlas_info.Atlas.EncodeToPNG());
GameObject.DestroyImmediate(atlas_info.Atlas, true);
AssetDatabase.ImportAsset(atlas_path);
@@ -175,6 +164,21 @@ namespace FlashTools.Internal {
Rects = rects};
}
static void RevertTexturePremultipliedAlpha(Texture2D texture) {
var pixels = texture.GetPixels();
for ( var i = 0; i < pixels.Length; ++i ) {
var c = pixels[i];
if ( c.a > 0 ) {
c.r /= c.a;
c.g /= c.a;
c.b /= c.a;
}
pixels[i] = c;
}
texture.SetPixels(pixels);
texture.Apply();
}
// ---------------------------------------------------------------------
//
// ConfigureAtlas
@@ -248,44 +252,45 @@ namespace FlashTools.Internal {
//
// ---------------------------------------------------------------------
static void ConfigureClips(SwfAsset asset) {
static SwfAssetData ConfigureClips(SwfAsset asset, SwfAssetData data) {
asset.Clips = asset.Clips.Where(p => !!p).ToList();
foreach ( var symbol in asset.Data.Symbols ) {
ConfigureClip(asset, symbol);
foreach ( var symbol in data.Symbols ) {
ConfigureClip(asset, data, symbol);
}
return data;
}
static void ConfigureClip(SwfAsset asset, SwfSymbolData symbol) {
static void ConfigureClip(SwfAsset asset, SwfAssetData data, SwfSymbolData symbol) {
var clip_asset = asset.Clips.FirstOrDefault(p => p.Name == symbol.Name);
if ( clip_asset ) {
ConfigureClipAsset(clip_asset, asset, symbol);
ConfigureClipAsset(clip_asset, asset, data, symbol);
AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(clip_asset));
} 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 => {
ConfigureClipAsset(new_clip_asset, asset, symbol);
ConfigureClipAsset(new_clip_asset, asset, data, symbol);
asset.Clips.Add(new_clip_asset);
});
}
}
static void ConfigureClipAsset(
SwfClipAsset clip_asset, SwfAsset asset, SwfSymbolData symbol)
SwfClipAsset clip_asset, SwfAsset asset, SwfAssetData data, SwfSymbolData symbol)
{
clip_asset.Name = symbol.Name;
clip_asset.Atlas = asset.Atlas;
clip_asset.FrameRate = asset.Data.FrameRate;
clip_asset.Sequences = LoadClipSequences(asset, symbol);
clip_asset.FrameRate = data.FrameRate;
clip_asset.Sequences = LoadClipSequences(asset, data, symbol);
}
static List<SwfClipAsset.Sequence> LoadClipSequences(
SwfAsset asset, SwfSymbolData symbol)
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, frame);
var baked_frame = BakeClipFrame(asset, data, frame);
if ( !string.IsNullOrEmpty(frame.Name) &&
(sequences.Count < 1 || sequences.Last().Name != frame.Name) )
{
@@ -316,7 +321,7 @@ namespace FlashTools.Internal {
}
static SwfClipAsset.Frame BakeClipFrame(
SwfAsset asset, SwfFrameData frame)
SwfAsset asset, SwfAssetData data, SwfFrameData frame)
{
List<uint> baked_uvs = new List<uint>();
List<uint> baked_mulcolors = new List<uint>();
@@ -327,7 +332,7 @@ namespace FlashTools.Internal {
foreach ( var inst in frame.Instances ) {
var bitmap = inst != null
? FindBitmapFromAssetData(asset.Data, inst.Bitmap)
? FindBitmapFromAssetData(data, inst.Bitmap)
: null;
if ( bitmap != null && IsVisibleInstance(inst) ) {
var width = bitmap.RealWidth / 20.0f;
@@ -355,14 +360,14 @@ namespace FlashTools.Internal {
uint mul_pack0, mul_pack1;
SwfUtils.PackFColorToUInts(
inst.ColorTrans.Mul,
inst.ColorTrans.mulColor,
out mul_pack0, out mul_pack1);
baked_mulcolors.Add(mul_pack0);
baked_mulcolors.Add(mul_pack1);
uint add_pack0, add_pack1;
SwfUtils.PackFColorToUInts(
inst.ColorTrans.Add,
inst.ColorTrans.addColor,
out add_pack0, out add_pack1);
baked_addcolors.Add(add_pack0);
baked_addcolors.Add(add_pack1);

View File

@@ -34,7 +34,7 @@ namespace FlashTools.Internal {
static void SafeLoadSwfAsset(string swf_path, SwfAsset swf_asset) {
try {
var new_data = LoadSwfAssetData(swf_path);
swf_asset.Data = new_data;
swf_asset.Data = SwfEditorUtils.CompressAsset(new_data);
swf_asset.Converting = new SwfAsset.ConvertingState();
} catch ( Exception e ) {
Debug.LogErrorFormat(

View File

@@ -4,6 +4,9 @@ using UnityEditor;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using Ionic.Zlib;
namespace FlashTools.Internal {
public static class SwfEditorUtils {
@@ -66,6 +69,33 @@ namespace FlashTools.Internal {
return asset;
}
public static byte[] CompressAsset<T>(T asset) {
var bytes = AssetToBytes(asset);
var result = ZlibStream.CompressBuffer(bytes);
return result;
}
public static T DecompressAsset<T>(byte[] data) {
var bytes = ZlibStream.UncompressBuffer(data);
var result = BytesToAsset<T>(bytes);
return result;
}
static byte[] AssetToBytes<T>(T asset) {
var formatter = new BinaryFormatter();
using ( var stream = new MemoryStream() ) {
formatter.Serialize(stream, asset);
return stream.ToArray();
}
}
static T BytesToAsset<T>(byte[] bytes) {
var formatter = new BinaryFormatter();
using ( var stream = new MemoryStream(bytes) ) {
return (T)formatter.Deserialize(stream);
}
}
// ---------------------------------------------------------------------
//
// Internal

View File

@@ -62,14 +62,14 @@ namespace FlashTools.Internal.SwfTools.SwfTypes {
public SwfColorTransData ToColorTransData() {
var trans = SwfColorTransData.identity;
if ( HasAdd ) {
trans.Add = new Vector4(
trans.addColor = new SwfVec4Data(
RAdd / 256.0f,
GAdd / 256.0f,
BAdd / 256.0f,
AAdd / 256.0f);
}
if ( HasMul ) {
trans.Mul = new Vector4(
trans.mulColor = new SwfVec4Data(
RMul / 256.0f,
GMul / 256.0f,
BMul / 256.0f,

View File

@@ -96,7 +96,7 @@ namespace FlashTools.Internal {
}
public static void PackFColorToUInts(
Vector4 v,
SwfVec4Data v,
out uint pack0, out uint pack1)
{
PackFColorToUInts(v.x, v.y, v.z, v.w, out pack0, out pack1);

View File

@@ -3,58 +3,126 @@ using FlashTools.Internal;
using System.Collections.Generic;
namespace FlashTools {
[System.Serializable]
public struct SwfVec2Data {
public float x;
public float y;
public SwfVec2Data(float x, float y) {
this.x = x;
this.y = y;
}
public static SwfVec2Data one {
get { return new SwfVec2Data(1.0f, 1.0f); }
}
public static SwfVec2Data zero {
get { return new SwfVec2Data(0.0f, 0.0f); }
}
}
[System.Serializable]
public struct SwfVec4Data {
public float x;
public float y;
public float z;
public float w;
public SwfVec4Data(float x, float y, float z, float w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public static SwfVec4Data one {
get { return new SwfVec4Data(1.0f, 1.0f, 1.0f, 1.0f); }
}
public static SwfVec4Data zero {
get { return new SwfVec4Data(0.0f, 0.0f, 0.0f, 0.0f); }
}
}
[System.Serializable]
public struct SwfRectData {
public float xMin;
public float xMax;
public float yMin;
public float yMax;
public static SwfRectData identity {
get {
return new SwfRectData{
xMin = 0.0f,
xMax = 0.0f,
yMin = 0.0f,
yMax = 0.0f};
}
}
public static SwfRectData FromURect(Rect rect) {
return new SwfRectData{
xMin = rect.xMin,
xMax = rect.xMax,
yMin = rect.yMin,
yMax = rect.yMax};
}
}
[System.Serializable]
public struct SwfMatrixData {
public Vector2 Sc;
public Vector2 Sk;
public Vector2 Tr;
public SwfVec2Data sc;
public SwfVec2Data sk;
public SwfVec2Data tr;
public static SwfMatrixData identity {
get {
return new SwfMatrixData{
Sc = Vector2.one,
Sk = Vector2.zero,
Tr = Vector2.zero};
sc = SwfVec2Data.one,
sk = SwfVec2Data.zero,
tr = SwfVec2Data.zero};
}
}
public Matrix4x4 ToUMatrix() {
var mat = Matrix4x4.identity;
mat.m00 = Sc.x;
mat.m11 = Sc.y;
mat.m10 = Sk.x;
mat.m01 = Sk.y;
mat.m03 = Tr.x;
mat.m13 = Tr.y;
mat.m00 = sc.x;
mat.m11 = sc.y;
mat.m10 = sk.x;
mat.m01 = sk.y;
mat.m03 = tr.x;
mat.m13 = tr.y;
return mat;
}
public static SwfMatrixData FromUMatrix(Matrix4x4 mat) {
return new SwfMatrixData{
Sc = new Vector2(mat.m00, mat.m11),
Sk = new Vector2(mat.m10, mat.m01),
Tr = new Vector2(mat.m03, mat.m13)};
sc = new SwfVec2Data(mat.m00, mat.m11),
sk = new SwfVec2Data(mat.m10, mat.m01),
tr = new SwfVec2Data(mat.m03, mat.m13)};
}
}
[System.Serializable]
public struct SwfColorTransData {
public Vector4 Mul;
public Vector4 Add;
public SwfVec4Data mulColor;
public SwfVec4Data addColor;
public Color ApplyToColor(Color color) {
return new Color(
Mathf.Clamp01(color.r * Mul.x + Add.x),
Mathf.Clamp01(color.g * Mul.y + Add.y),
Mathf.Clamp01(color.b * Mul.z + Add.z),
Mathf.Clamp01(color.a * Mul.w + Add.w));
Mathf.Clamp01(color.r * mulColor.x + addColor.x),
Mathf.Clamp01(color.g * mulColor.y + addColor.y),
Mathf.Clamp01(color.b * mulColor.z + addColor.z),
Mathf.Clamp01(color.a * mulColor.w + addColor.w));
}
public static SwfColorTransData identity {
get {
return new SwfColorTransData{
Mul = Vector4.one,
Add = Vector4.zero};
mulColor = SwfVec4Data.one,
addColor = SwfVec4Data.zero};
}
}
@@ -62,16 +130,16 @@ namespace FlashTools {
SwfColorTransData a, SwfColorTransData b)
{
return new SwfColorTransData{
Mul = new Vector4(
b.Mul.x * a.Mul.x,
b.Mul.y * a.Mul.y,
b.Mul.z * a.Mul.z,
b.Mul.w * a.Mul.w),
Add = new Vector4(
b.Add.x * a.Mul.x + a.Add.x,
b.Add.y * a.Mul.y + a.Add.y,
b.Add.z * a.Mul.z + a.Add.z,
b.Add.w * a.Mul.w + a.Add.w)};
mulColor = new SwfVec4Data(
b.mulColor.x * a.mulColor.x,
b.mulColor.y * a.mulColor.y,
b.mulColor.z * a.mulColor.z,
b.mulColor.w * a.mulColor.w),
addColor = new SwfVec4Data(
b.addColor.x * a.mulColor.x + a.addColor.x,
b.addColor.y * a.mulColor.y + a.addColor.y,
b.addColor.z * a.mulColor.z + a.addColor.z,
b.addColor.w * a.mulColor.w + a.addColor.w)};
}
}
@@ -109,7 +177,7 @@ namespace FlashTools {
public ushort Redirect = 0;
public int RealWidth = 0;
public int RealHeight = 0;
public Rect SourceRect = new Rect();
public SwfRectData SourceRect = SwfRectData.identity;
}
[System.Serializable]
@@ -125,7 +193,7 @@ namespace FlashTools {
public int Stage;
}
[HideInInspector]
public SwfAssetData Data;
public byte[] Data;
[SwfReadOnly]
public Texture2D Atlas;
[HideInInspector]
@@ -139,7 +207,7 @@ namespace FlashTools {
#if UNITY_EDITOR
void Reset() {
Data = new SwfAssetData();
Data = new byte[0];
Atlas = null;
Clips = new List<SwfClipAsset>();
Settings = SwfSettings.GetDefault();