backed animation wip

This commit is contained in:
2016-08-24 20:54:01 +07:00
parent a48e01b278
commit cfdebd566a
7 changed files with 343 additions and 11 deletions

View File

@@ -48,6 +48,7 @@
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfAnimationAssetEditor.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfAnimationAssetPostprocessor.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfAnimationEditor.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfBakedAnimationEditor.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfPostprocessor.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfPropertyDrawers.cs" />
<Compile Include="Assets\FlashTools\Scripts\Internal\Editor\SwfTools\SwfContext.cs" />

View File

@@ -49,6 +49,7 @@
<Compile Include="Assets\FlashTools\Scripts\Internal\SwfPropertyAttributes.cs" />
<Compile Include="Assets\FlashTools\Scripts\SwfAnimation.cs" />
<Compile Include="Assets\FlashTools\Scripts\SwfAnimationAsset.cs" />
<Compile Include="Assets\FlashTools\Scripts\SwfBakedAnimation.cs" />
<None Include="Assets\FlashTools\Resources\Shaders\SwfDecrMask.shader" />
<None Include="Assets\FlashTools\Resources\Shaders\SwfSimple.shader" />
<None Include="Assets\FlashTools\Resources\Shaders\SwfIncrMask.shader" />

View File

@@ -59,19 +59,24 @@ namespace FlashTools.Internal {
}
}
GameObject CreateAnimationGO() {
GameObject CreateAnimationGO(bool baked) {
if ( _asset ) {
var anim_go = new GameObject(_asset.name);
anim_go.AddComponent<MeshFilter>();
anim_go.AddComponent<MeshRenderer>();
if ( baked ) {
anim_go.AddComponent<SwfBakedAnimation>().Asset = _asset;
anim_go.GetComponent<SwfBakedAnimation>().BakeFrameMeshes();
} else {
anim_go.AddComponent<SwfAnimation>().Asset = _asset;
}
return anim_go;
}
return null;
}
void CreateAnimationPrefab() {
var anim_go = CreateAnimationGO();
void CreateAnimationPrefab(bool baked) {
var anim_go = CreateAnimationGO(baked);
if ( anim_go ) {
var prefab_path = GetPrefabPath();
if ( !string.IsNullOrEmpty(prefab_path) ) {
@@ -88,8 +93,8 @@ namespace FlashTools.Internal {
}
}
void CreateAnimationOnScene() {
var anim_go = CreateAnimationGO();
void CreateAnimationOnScene(bool baked) {
var anim_go = CreateAnimationGO(baked);
if ( anim_go ) {
Undo.RegisterCreatedObjectUndo(anim_go, "Create SwfAnimation");
}
@@ -119,18 +124,18 @@ namespace FlashTools.Internal {
GUI.enabled = false;
var script_prop = serializedObject.FindProperty("m_Script");
if ( script_prop != null ) {
EditorGUILayout.PropertyField(script_prop);
EditorGUILayout.PropertyField(script_prop, true);
}
var atlas_prop = serializedObject.FindProperty("Atlas");
if ( atlas_prop != null ) {
EditorGUILayout.PropertyField(atlas_prop);
EditorGUILayout.PropertyField(atlas_prop, true);
}
GUI.enabled = true;
_settingsFoldout = EditorGUILayout.Foldout(_settingsFoldout, "Settings");
if ( _settingsFoldout ) {
var it = serializedObject.FindProperty("Overridden");
while ( it.NextVisible(true) ) {
EditorGUILayout.PropertyField(it);
EditorGUILayout.PropertyField(it, true);
}
DrawGUISettingsControls();
}
@@ -162,10 +167,20 @@ namespace FlashTools.Internal {
GUILayout.BeginHorizontal();
{
if ( GUILayout.Button("Create animation prefab") ) {
CreateAnimationPrefab();
CreateAnimationPrefab(false);
}
if ( GUILayout.Button("Create animation on scene") ) {
CreateAnimationOnScene();
CreateAnimationOnScene(false);
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
{
if ( GUILayout.Button("Create baked animation prefab") ) {
CreateAnimationPrefab(true);
}
if ( GUILayout.Button("Create baked animation on scene") ) {
CreateAnimationOnScene(true);
}
}
GUILayout.EndHorizontal();

View File

@@ -0,0 +1,27 @@
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
namespace FlashTools.Internal {
[CustomEditor(typeof(SwfBakedAnimation))]
public class SwfBakedAnimationEditor : Editor {
SwfBakedAnimation _animation = null;
void OnEnable() {
_animation = target as SwfBakedAnimation;
}
public override void OnInspectorGUI() {
DrawDefaultInspector();
if ( _animation.Asset && _animation.frameCount > 1 ) {
var new_current_frame = EditorGUILayout.IntSlider(
"Frame", _animation.currentFrame,
0, _animation.frameCount - 1);
if ( new_current_frame != _animation.currentFrame ) {
_animation.currentFrame = new_current_frame;
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7de32773fb5894d2a8e5b1f15f3b6549
timeCreated: 1472043063
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,264 @@
using UnityEngine;
using System.Collections.Generic;
using FlashTools.Internal;
namespace FlashTools {
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SwfBakedAnimation : MonoBehaviour {
public SwfAnimationAsset Asset = null;
[SwfSortingLayer]
public string SortingLayer = "Default";
public int SortingOrder = 0;
MeshFilter _meshFilter = null;
MeshRenderer _meshRenderer = null;
int _current_frame = 0;
float _frame_timer = 0.0f;
public int frameCount {
get { return Asset ? Asset.Data.Frames.Count : 0; }
}
public int currentFrame {
get { return _current_frame; }
set {
_current_frame = Mathf.Clamp(value, 0, frameCount - 1);
FixCurrentMesh();
}
}
// ------------------------------------------------------------------------
//
// Stuff
//
// ------------------------------------------------------------------------
static Material SwfIncrMask;
static Material SwfSimple;
static Material SwfDecrMask;
static Shader SwfMaskedShader;
MaterialPropertyBlock MatPropBlock;
class Frame {
public Mesh Mesh;
public Material[] Materials;
}
List<Frame> _frames = new List<Frame>();
class Group {
public SwfAnimationInstanceType Type;
public int ClipDepth;
public List<int> Triangles;
public Material Material;
}
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<Group> _groups = new List<Group>();
List<Material> _materials = new List<Material>();
void ClearTempBakeData() {
_uvs.Clear();
_mulcolors.Clear();
_addcolors.Clear();
_vertices.Clear();
_groups.Clear();
_materials.Clear();
}
public void BakeFrameMeshes() {
InitMaterials();
if ( Asset && Asset.Atlas && Asset.Data != null && Asset.Data.Frames.Count > 0 ) {
for ( var i = 0; i < Asset.Data.Frames.Count; ++i ) {
var frame = Asset.Data.Frames[i];
BakeFrameMesh(frame);
}
}
FixCurrentMesh();
}
void InitMaterials() {
if ( !SwfIncrMask ) {
Profiler.maxNumberOfSamplesPerFrame = -1;
SwfIncrMask = new Material(Shader.Find("FlashTools/SwfIncrMask"));
}
if ( !SwfSimple ) {
SwfSimple = new Material(Shader.Find("FlashTools/SwfSimple"));
}
if ( !SwfDecrMask ) {
SwfDecrMask = new Material(Shader.Find("FlashTools/SwfDecrMask"));
}
if ( !SwfMaskedShader ) {
SwfMaskedShader = Shader.Find("FlashTools/SwfMasked");
}
if ( MatPropBlock == null ) {
MatPropBlock = new MaterialPropertyBlock();
MatPropBlock.SetTexture("_MainTex", Asset.Atlas);
}
}
void BakeFrameMesh(SwfAnimationFrameData frame) {
for ( var i = 0; i < frame.Instances.Count; ++i ) {
var inst = frame.Instances[i];
var bitmap = inst != null ? FindBitmap(inst.Bitmap) : null;
if ( bitmap != null ) {
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 matrix =
Matrix4x4.Scale(new Vector3(
+1.0f / Asset.Settings.PixelsPerUnit,
-1.0f / Asset.Settings.PixelsPerUnit,
+1.0f / Asset.Settings.PixelsPerUnit)) * inst.Matrix;
_vertices.Add(matrix.MultiplyPoint3x4(v0));
_vertices.Add(matrix.MultiplyPoint3x4(v1));
_vertices.Add(matrix.MultiplyPoint3x4(v2));
_vertices.Add(matrix.MultiplyPoint3x4(v3));
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));
_uvs.Add(new Vector2(source_rect.xMax, source_rect.yMax));
_uvs.Add(new Vector2(source_rect.xMin, source_rect.yMax));
_mulcolors.Add(inst.ColorTransform.Mul);
_mulcolors.Add(inst.ColorTransform.Mul);
_mulcolors.Add(inst.ColorTransform.Mul);
_mulcolors.Add(inst.ColorTransform.Mul);
_addcolors.Add(inst.ColorTransform.Add);
_addcolors.Add(inst.ColorTransform.Add);
_addcolors.Add(inst.ColorTransform.Add);
_addcolors.Add(inst.ColorTransform.Add);
if ( _groups.Count == 0 ||
_groups[_groups.Count - 1].Type != inst.Type ||
_groups[_groups.Count - 1].ClipDepth != inst.ClipDepth )
{
_groups.Add(new Group{
Type = inst.Type,
ClipDepth = inst.ClipDepth,
Triangles = new List<int>(),
Material = null
});
}
_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);
}
}
for ( var i = 0; i < _groups.Count; ++i ) {
var group = _groups[i];
switch ( group.Type ) {
case SwfAnimationInstanceType.Mask:
group.Material = SwfIncrMask;
break;
case SwfAnimationInstanceType.Group:
group.Material = SwfSimple;
break;
case SwfAnimationInstanceType.Masked:
group.Material = new Material(SwfMaskedShader);
group.Material.SetInt("_StencilID", group.ClipDepth);
break;
case SwfAnimationInstanceType.MaskReset:
group.Material = SwfDecrMask;
break;
}
}
for ( var i = 0; i < _groups.Count; ++i ) {
var group = _groups[i];
_materials.Add(group.Material);
}
var mesh = new Mesh();
mesh.subMeshCount = _groups.Count;
mesh.SetVertices(_vertices);
for ( var i = 0; i < _groups.Count; ++i ) {
mesh.SetTriangles(_groups[i].Triangles, i);
}
mesh.SetUVs(0, _uvs);
mesh.SetUVs(1, _addcolors);
mesh.SetColors(_mulcolors);
mesh.RecalculateNormals();
_frames.Add(new Frame{
Mesh = mesh,
Materials = _materials.ToArray()});
ClearTempBakeData();
}
SwfAnimationBitmapData FindBitmap(int bitmap_id) {
if ( Asset ) {
for ( var i = 0; i < Asset.Data.Bitmaps.Count; ++i ) {
var bitmap = Asset.Data.Bitmaps[i];
if ( bitmap.Id == bitmap_id ) {
return bitmap;
}
}
}
return null;
}
void UpdateFrameTimer() {
if ( Asset ) {
if ( _frames.Count == 0 ) {
BakeFrameMeshes();
FixCurrentMesh();
}
_frame_timer += Asset.Data.FrameRate * Time.deltaTime;
while ( _frame_timer > 1.0f ) {
_frame_timer -= 1.0f;
++_current_frame;
if ( _current_frame > frameCount - 1 ) {
_current_frame = 0;
}
FixCurrentMesh();
}
}
}
void FixCurrentMesh() {
if ( _frames.Count > 0 ) {
var frame = _frames[Mathf.Clamp(currentFrame, 0, _frames.Count)];
_meshFilter.sharedMesh = frame.Mesh;
_meshRenderer.sharedMaterials = frame.Materials;
_meshRenderer.sortingOrder = SortingOrder;
_meshRenderer.sortingLayerName = SortingLayer;
_meshRenderer.SetPropertyBlock(MatPropBlock);
}
}
// ------------------------------------------------------------------------
//
// Messages
//
// ------------------------------------------------------------------------
void Awake() {
_meshFilter = GetComponent<MeshFilter>();
_meshRenderer = GetComponent<MeshRenderer>();
}
void Update() {
UpdateFrameTimer();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 950d548c7e22f4e25a47de474b49e86e
timeCreated: 1472040299
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: