very dirty mask impl

This commit is contained in:
2016-07-22 00:13:00 +06:00
parent 616b5234b9
commit 96026c0387
17 changed files with 311 additions and 47 deletions

View File

@@ -1,7 +1,7 @@
fileFormatVersion: 2
guid: 65fdba8df418b457b880b3079a77808e
guid: 6e85e1b855132498dbf40b445321b10a
folderAsset: yes
timeCreated: 1468071959
timeCreated: 1469040567
licenseType: Free
DefaultImporter:
userData:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b35df03959664427b81baa14dbe54e3b
timeCreated: 1468951556
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: 6
orthographic size: 2
m_Depth: -1
m_CullingMask:
serializedVersion: 2

View File

@@ -208,10 +208,13 @@ namespace FlashTools {
//Debug.LogFormat("Cur frame: {0}", _current_frame);
}
} else {
#if UNITY_EDITOR
OnValidate();
#endif
}
}
#if UNITY_EDITOR
void OnValidate() {
if ( Asset ) {
_lastAssetPath = AssetDatabase.GetAssetPath(Asset);
@@ -222,6 +225,7 @@ namespace FlashTools {
}
}
}
#endif
void OnRenderObject() {
if ( Asset ) {

View File

@@ -72,6 +72,8 @@ namespace FlashTools.Internal {
return AddDisplayListToFrame(
context,
context.DisplayList,
0,
0,
Matrix4x4.identity,
SwfAnimationColorTransform.identity,
frame);
@@ -79,10 +81,10 @@ namespace FlashTools.Internal {
static SwfAnimationFrameData AddDisplayListToFrame(
SwfContext ctx, SwfDisplayList dl,
Matrix4x4 parent_matrix, SwfAnimationColorTransform parent_color_transform,
ushort parent_depth, ushort parent_clip_depth, Matrix4x4 parent_matrix, SwfAnimationColorTransform parent_color_transform,
SwfAnimationFrameData frame)
{
foreach ( var inst in dl.Instances.Values.Where(p => p.Visible && p.ClipDepth == 0) ) {
foreach ( var inst in dl.Instances.Values.Where(p => p.Visible) ) {
switch ( inst.Type ) {
case SwfDisplayInstanceType.Shape:
var shape_def = ctx.Library.FindDefine<SwfLibraryShapeDefine>(inst.Id);
@@ -94,6 +96,8 @@ namespace FlashTools.Internal {
var bitmap_def = ctx.Library.FindDefine<SwfLibraryBitmapDefine>(bitmap_id);
if ( bitmap_def != null ) {
frame.Instances.Add(new SwfAnimationInstanceData{
Depth = (ushort)(parent_depth + inst.Depth - 1),
ClipDepth = (ushort)(parent_clip_depth != 0 ? parent_clip_depth : inst.ClipDepth),
Bitmap = bitmap_id,
Matrix = parent_matrix * inst.Matrix.ToUnityMatrix() * bitmap_matrix.ToUnityMatrix(),
ColorTransform = parent_color_transform * inst.ColorTransform.ToAnimationColorTransform()});
@@ -108,6 +112,8 @@ namespace FlashTools.Internal {
AddDisplayListToFrame(
ctx,
sprite_inst.DisplayList,
(ushort)(parent_depth + sprite_inst.Depth),
(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);

View File

@@ -1,22 +1,41 @@
using UnityEngine;
using UnityEditor;
using System.Linq;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace FlashTools {
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SwfAnimation : MonoBehaviour {
public SwfAnimationAsset Asset = null;
public SwfAnimationAsset Asset = null;
public int GroupCount = 0;
int _current_frame = 0;
float _frame_timer = 0.0f;
string _last_asset_path = string.Empty;
List<Vector2> _uvs = new List<Vector2>();
List<Color> _mulcolors = new List<Color>();
List<Vector4> _addcolors = new List<Vector4>();
List<Vector3> _vertices = new List<Vector3>();
List<int> _triangles = new List<int>();
List<Vector2> _uvs = new List<Vector2>();
List<Color> _mulcolors = new List<Color>();
List<Vector4> _addcolors = new List<Vector4>();
List<Vector3> _vertices = new List<Vector3>();
enum GroupType {
Mask,
Masked,
Group
}
class Group {
public GroupType Type;
public List<int> Triangles;
public int ClipDepth;
public Material Material;
}
List<Group> _groups = new List<Group>();
public int frameCount {
get { return Asset ? Asset.Data.Frames.Count : 0; }
@@ -33,15 +52,6 @@ namespace FlashTools {
//
// ------------------------------------------------------------------------
void Start() {
if ( Asset && Asset.Atlas ) {
var material = new Material(Shader.Find("FlashTools/FlashAnim"));
material.SetTexture("_MainTex", Asset.Atlas);
material.SetInt("_StencilID", 0);
GetComponent<MeshRenderer>().sharedMaterial = material;
}
}
void Update() {
if ( Asset ) {
_frame_timer += Asset.Data.FrameRate * Time.deltaTime;
@@ -53,10 +63,13 @@ namespace FlashTools {
}
}
} else {
#if UNITY_EDITOR
OnValidate();
#endif
}
}
#if UNITY_EDITOR
void OnValidate() {
if ( Asset ) {
_last_asset_path = AssetDatabase.GetAssetPath(Asset);
@@ -67,6 +80,7 @@ namespace FlashTools {
}
}
}
#endif
SwfAnimationBitmapData FindBitmap(int bitmap_id) {
if ( Asset ) {
@@ -83,10 +97,13 @@ namespace FlashTools {
void OnRenderObject() {
if ( Asset ) {
_vertices.Clear();
_triangles.Clear();
_uvs.Clear();
_mulcolors.Clear();
_addcolors.Clear();
_groups.Clear();
var last_group_id = 0;
var last_clip_depth = 0;
var frame = Asset.Data.Frames[currentFrame];
foreach ( var inst in frame.Instances ) {
@@ -95,10 +112,10 @@ namespace FlashTools {
var width = bitmap.RealSize.x / 20.0f;
var height = bitmap.RealSize.y / 20.0f;
var v0 = new Vector3( 0, 0, 0);
var v1 = new Vector3( width, 0, 0);
var v2 = new Vector3( width, height, 0);
var v3 = new Vector3( 0, height, 0);
var v0 = new Vector3( 0, 0, 0);
var v1 = new Vector3(width, 0, 0);
var v2 = new Vector3(width, height, 0);
var v3 = new Vector3( 0, height, 0);
var matrix =
Matrix4x4.Scale(new Vector3(
@@ -111,13 +128,6 @@ namespace FlashTools {
_vertices.Add(matrix.MultiplyPoint3x4(v2));
_vertices.Add(matrix.MultiplyPoint3x4(v3));
_triangles.Add(_vertices.Count - 4 + 2);
_triangles.Add(_vertices.Count - 4 + 1);
_triangles.Add(_vertices.Count - 4 + 0);
_triangles.Add(_vertices.Count - 4 + 0);
_triangles.Add(_vertices.Count - 4 + 3);
_triangles.Add(_vertices.Count - 4 + 2);
var source_rect = bitmap.SourceRect;
_uvs.Add(new Vector2(source_rect.xMin, source_rect.yMin));
_uvs.Add(new Vector2(source_rect.xMax, source_rect.yMin));
@@ -133,17 +143,163 @@ namespace FlashTools {
_addcolors.Add(inst.ColorTransform.Add);
_addcolors.Add(inst.ColorTransform.Add);
_addcolors.Add(inst.ColorTransform.Add);
if ( inst.ClipDepth != 0 ) {
var gr = new Group();
gr.Type = GroupType.Mask;
gr.Triangles = new List<int>();
gr.ClipDepth = inst.ClipDepth;
_groups.Add(gr);
} else {
if ( _groups.Count == 0 ) {
var gr = new Group();
gr.Type = GroupType.Group;
gr.Triangles = new List<int>();
gr.ClipDepth = 0;
_groups.Add(gr);
} else {
var last_group = _groups[_groups.Count - 1];
if ( last_group.Type == GroupType.Mask ) {
if ( inst.Depth < last_group.ClipDepth ) {
var gr = new Group();
gr.Type = GroupType.Masked;
gr.Triangles = new List<int>();
gr.ClipDepth = last_group.ClipDepth;
_groups.Add(gr);
} else {
var gr = new Group();
gr.Type = GroupType.Group;
gr.Triangles = new List<int>();
gr.ClipDepth = 0;
_groups.Add(gr);
}
} else if ( last_group.Type == GroupType.Masked ) {
if ( inst.Depth < last_group.ClipDepth ) {
// nothing
} else {
var gr = new Group();
gr.Type = GroupType.Group;
gr.Triangles = new List<int>();
gr.ClipDepth = 0;
_groups.Add(gr);
}
} else if ( last_group.Type == GroupType.Group ) {
// nothing
}
}
}
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 2);
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 1);
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 0);
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 0);
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 3);
_groups[_groups.Count - 1].Triangles.Add(_vertices.Count - 4 + 2);
/*
if ( inst.ClipDepth != 0 ) {
++last_group_id;
last_clip_depth = inst.ClipDepth;
var gr = new Group();
gr.Type = GroupType.Mask;
gr.Triangles = new List<int>();
_groups.Add(gr);
//_triangles.Add(new List<int>());
//var material = new Material(Shader.Find("FlashTools/FlashMask"));
//material.SetTexture("_MainTex", Asset.Atlas);
//material.SetInt("_StencilID", last_group_id);
//materials.Add(material);
} else if ( inst.Depth < last_clip_depth ) {
if ( _groups.Count == 0 || _groups[_groups.Count - 1].Type != GroupType.Masked ) {
var gr = new Group();
gr.Type = GroupType.Masked;
gr.Triangles = new List<int>();
_groups.Add(gr);
}
} else if ( (inst.Depth >= last_clip_depth && last_clip_depth > 0) || _groups.Count == 0 ) {
var gr = new Group();
gr.Type = GroupType.Group;
gr.Triangles = new List<int>();
_groups.Add(gr);
}*/
/*
if ( inst.ClipDepth != 0 ) {
_triangles.Add(new List<int>());
++last_group_id;
last_clip_depth = inst.ClipDepth;
var material = new Material(Shader.Find("FlashTools/FlashMask"));
material.SetTexture("_MainTex", Asset.Atlas);
material.SetInt("_StencilID", last_group_id);
materials.Add(material);
} else if ( inst.Depth < last_clip_depth ) {
var material = new Material(Shader.Find("FlashTools/FlashMasked"));
material.SetTexture("_MainTex", Asset.Atlas);
material.SetInt("_StencilID", last_group_id);
materials.Add(material);
} else if ( (inst.Depth >= last_clip_depth && last_clip_depth > 0) || materials.Count == 0 ) {
_triangles.Add(new List<int>());
++last_group_id;
last_clip_depth = 0;
var material = new Material(Shader.Find("FlashTools/FlashAnim"));
material.SetTexture("_MainTex", Asset.Atlas);
material.SetInt("_StencilID", 0);
materials.Add(material);
}*/
/*
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 2);
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 1);
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 0);
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 0);
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 3);
_triangles[_triangles.Count - 1].Add(_vertices.Count - 4 + 2);*/
/*
if ( inst.ClipDepth != 0 ) {
_triangles.Add(new List<int>());
}*/
}
}
var full_groups = _groups.Where(p => p.Triangles.Count > 0).ToArray();
for ( var i = 0; i < full_groups.Length; ++i ) {
var gr = full_groups[i];
switch ( gr.Type ) {
case GroupType.Mask:
gr.Material = new Material(Shader.Find("FlashTools/FlashMask"));
gr.Material.SetTexture("_MainTex", Asset.Atlas);
gr.Material.SetInt("_StencilID", i+1);
break;
case GroupType.Masked:
gr.Material = new Material(Shader.Find("FlashTools/FlashMasked"));
gr.Material.SetTexture("_MainTex", Asset.Atlas);
gr.Material.SetInt("_StencilID", i);
break;
case GroupType.Group:
gr.Material = new Material(Shader.Find("FlashTools/FlashAnim"));
gr.Material.SetTexture("_MainTex", Asset.Atlas);
gr.Material.SetInt("_StencilID", 0);
break;
}
}
GetComponent<MeshRenderer>().sharedMaterials = full_groups.Select(p => p.Material).ToArray();
var mesh_filter = GetComponent<MeshFilter>();
if ( mesh_filter ) {
var mesh = mesh_filter.sharedMesh
? mesh_filter.sharedMesh
: new Mesh();
mesh.Clear();
mesh.subMeshCount = full_groups.Length;
GroupCount = full_groups.Length;
mesh.SetVertices(_vertices);
mesh.SetTriangles(_triangles, 0);
for ( var i = 0; i < full_groups.Length; ++i ) {
mesh.SetTriangles(full_groups[i].Triangles, i);
}
mesh.SetUVs(0, _uvs);
mesh.SetUVs(1, _addcolors);
mesh.SetColors(_mulcolors);

View File

@@ -38,6 +38,8 @@ namespace FlashTools {
[System.Serializable]
public class SwfAnimationInstanceData {
public ushort Depth = 0;
public ushort ClipDepth = 0;
public ushort Bitmap = 0;
public Matrix4x4 Matrix = Matrix4x4.identity;
public SwfAnimationColorTransform ColorTransform = SwfAnimationColorTransform.identity;

View File

@@ -1,12 +1,12 @@
Shader "FlashTools/FlashAnim" {
Properties {
[PerRendererData] _MainTex ("Main Texture", 2D ) = "white" {}
[PerRendererData] _StencilID ("Stencil ID" , Int) = 0
_StencilID ("Stencil ID" , Int) = 0
}
SubShader {
Tags {
"Queue" = "Transparent+1"
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
@@ -20,10 +20,8 @@ Shader "FlashTools/FlashAnim" {
Pass {
Stencil {
Ref [_StencilID]
Comp Equal
Pass Keep
Fail Keep
Ref [_StencilID]
Comp always
}
CGPROGRAM
#pragma vertex vert

View File

@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: f1e8cd2344e824b6a9b12efcacde262c
timeCreated: 1456948894
guid: 71f5f783ce2ab4fc4bf826e4acb105dd
timeCreated: 1469113422
licenseType: Free
ShaderImporter:
defaultTextures: []

View File

@@ -1,7 +1,7 @@
Shader "FlashTools/FlashMask" {
Properties {
[PerRendererData] _MainTex ("Main Texture", 2D ) = "white" {}
[PerRendererData] _StencilID ("Stencil ID" , Int) = 0
_StencilID ("Stencil ID" , Int) = 0
}
SubShader {
@@ -21,7 +21,7 @@ Shader "FlashTools/FlashMask" {
Pass {
Stencil {
Ref [_StencilID]
Ref [_StencilID]
Comp always
Pass replace
}
@@ -54,7 +54,6 @@ Shader "FlashTools/FlashMask" {
if ( c.a < 0.01 ) {
discard;
}
c.rgb *= c.a;
return c;
}
ENDCG

View File

@@ -0,0 +1,78 @@
Shader "FlashTools/FlashMasked" {
Properties {
[PerRendererData] _MainTex ("Main Texture", 2D ) = "white" {}
_StencilID ("Stencil ID" , Int) = 0
}
SubShader {
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
"CanUseSpriteAtlas" = "True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass {
Stencil {
Ref [_StencilID]
Comp equal
}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 mulcolor : COLOR;
float4 addcolor : TEXCOORD1;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 mulcolor : COLOR;
fixed4 addcolor : TEXCOORD1;
};
v2f vert(appdata_t IN) {
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.uv = IN.uv;
OUT.mulcolor = IN.mulcolor;
OUT.addcolor = IN.addcolor;
return OUT;
}
sampler2D _MainTex;
sampler2D _AlphaTex;
float _AlphaSplitEnabled;
fixed4 SampleSpriteTexture(float2 uv) {
fixed4 color = tex2D(_MainTex, uv);
#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
if (_AlphaSplitEnabled)
color.a = tex2D(_AlphaTex, uv).r;
#endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED
return color;
}
fixed4 frag(v2f IN) : SV_Target {
fixed4 c = SampleSpriteTexture(IN.uv);
if ( c.a > 0.01 ) {
c = c * IN.mulcolor + IN.addcolor;
}
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: f1e8cd2344e824b6a9b12efcacde262c
timeCreated: 1456948894
licenseType: Free
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant: