going to open source

This commit is contained in:
2016-12-03 03:03:22 +07:00
parent 215b3b652a
commit 711bbfd1a4
195 changed files with 1793 additions and 465 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: e790c4a404b2b49e5bbdaa24beb79591
folderAsset: yes
timeCreated: 1480698333
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using System.Collections.Generic;
namespace FTRuntime.Internal {
class SwfAssocList<T> {
SwfList<T> _list;
Dictionary<T, int> _dict;
IEqualityComparer<T> _comp;
public SwfAssocList() {
_list = new SwfList<T>();
_dict = new Dictionary<T, int>();
_comp = EqualityComparer<T>.Default;
}
public SwfAssocList(int capacity) {
_list = new SwfList<T>(capacity);
_dict = new Dictionary<T, int>(capacity);
_comp = EqualityComparer<T>.Default;
}
public T this[int index] {
get {
return _list[index];
}
}
public int this[T item] {
get {
return _dict[item];
}
}
public int Count {
get {
return _list.Count;
}
}
public bool Contains(T value) {
return _dict.ContainsKey(value);
}
public void Add(T item) {
if ( !_dict.ContainsKey(item) ) {
_dict.Add(item, _list.Count);
_list.Push(item);
}
}
public void Remove(T item) {
int index;
if ( _dict.TryGetValue(item, out index) ) {
_dict.Remove(item);
var reordered =_list.UnorderedRemoveAt(index);
if ( !_comp.Equals(reordered, item) ) {
_dict[reordered] = index;
}
}
}
public void Clear() {
_list.Clear();
_dict.Clear();
}
public void AssignTo(List<T> list) {
_list.AssignTo(list);
}
public void AssignTo(SwfList<T> list) {
_list.AssignTo(list);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0be120270cd2f400d87dcae1f0e0c43f
timeCreated: 1480698333
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
namespace FTRuntime.Internal {
class SwfList<T> {
T[] _data;
int _size;
static readonly T[] _emptyData = new T[0];
const int _defaultCapacity = 4;
public SwfList() {
_data = _emptyData;
_size = 0;
}
public SwfList(int capacity) {
if ( capacity < 0 ) {
throw new ArgumentOutOfRangeException(
"capacity", "capacity must be >= 0");
} else if ( capacity == 0 ) {
_data = _emptyData;
_size = 0;
} else {
_data = new T[capacity];
_size = 0;
}
}
public void Push(T value) {
if ( _size == _data.Length ) {
var new_capacity = _size == 0
? _defaultCapacity : _size * 2;
var new_data = new T[new_capacity];
Array.Copy(_data, new_data, _size);
_data = new_data;
}
_data[_size++] = value;
}
public T Pop() {
if ( _size == 0 ) {
throw new InvalidOperationException("empty list");
}
var last = _data[--_size];
_data[_size] = default(T);
return last;
}
public T Peek() {
if ( _size == 0 ) {
throw new InvalidOperationException("empty list");
}
return _data[_size - 1];
}
public void Clear() {
Array.Clear(_data, 0, _size);
_size = 0;
}
public T UnorderedRemoveAt(int index) {
if ( (uint)index >= (uint)_size ) {
throw new IndexOutOfRangeException();
}
var last = _data[_size - 1];
_data[index] = last;
_data[--_size] = default(T);
return last;
}
public T this[int index] {
get {
if ( (uint)index >= (uint)_size ) {
throw new IndexOutOfRangeException();
}
return _data[index];
}
set {
if ( (uint)index >= (uint)_size ) {
throw new IndexOutOfRangeException();
}
_data[index] = value;
}
}
public int Count {
get { return _size; }
}
public int Capacity {
get { return _data.Length; }
set {
if ( value < _size ) {
throw new ArgumentOutOfRangeException("capacity");
}
if ( value != _data.Length ) {
if ( value > 0 ) {
var new_data = new T[value];
if ( _size > 0 ) {
Array.Copy(_data, new_data, _size);
}
_data = new_data;
} else {
_data = _emptyData;
}
}
}
}
public void AssignTo(List<T> list) {
list.Clear();
if ( list.Capacity < Count ) {
list.Capacity = Count * 2;
}
for ( int i = 0, e = Count; i < e; ++i ) {
list.Add(this[i]);
}
}
public void AssignTo(SwfList<T> list) {
if ( list._data.Length < _size ) {
var new_data = new T[_size * 2];
Array.Copy(_data, new_data, _size);
list._data = new_data;
list._size = _size;
} else {
if ( _size < list._size ) {
Array.Clear(list._data, _size, list._size - _size);
}
if ( _size > 0 ) {
Array.Copy(_data, list._data, _size);
}
list._size = _size;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b3a27809c7ebd4cc68ddfa90f95dd9d7
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,160 @@
using UnityEngine;
using System.Collections.Generic;
namespace FTRuntime.Internal {
static class SwfUtils {
const ushort UShortMax = ushort.MaxValue;
const float FColorPrecision = 1.0f / 512.0f;
const float InvFColorPrecision = 1.0f / FColorPrecision;
public static void UnpackUV(uint pack, out float u, out float v) {
u = (float)((pack >> 16) & 0xFFFF) / UShortMax;
v = (float)((pack ) & 0xFFFF) / UShortMax;
}
public static void UnpackFColorFromUInts(
uint pack0, uint pack1,
out float c0, out float c1, out float c2, out float c3)
{
c0 = (short)((pack0 >> 16) & 0xFFFF) / InvFColorPrecision;
c1 = (short)((pack0 ) & 0xFFFF) / InvFColorPrecision;
c2 = (short)((pack1 >> 16) & 0xFFFF) / InvFColorPrecision;
c3 = (short)((pack1 ) & 0xFFFF) / InvFColorPrecision;
}
//
//
//
public static void FillGeneratedMesh(Mesh mesh, SwfClipAsset.MeshData mesh_data) {
if ( mesh_data.SubMeshes.Length > 0 ) {
mesh.subMeshCount = mesh_data.SubMeshes.Length;
GeneratedMeshCache.FillVertices(mesh_data.Vertices);
mesh.SetVertices(GeneratedMeshCache.Vertices);
for ( int i = 0, e = mesh_data.SubMeshes.Length; i < e; ++i ) {
GeneratedMeshCache.FillTriangles(
mesh_data.SubMeshes[i].StartVertex,
mesh_data.SubMeshes[i].IndexCount);
mesh.SetTriangles(GeneratedMeshCache.Indices, i);
}
GeneratedMeshCache.FillUVs(mesh_data.UVs);
mesh.SetUVs(0, GeneratedMeshCache.UVs);
GeneratedMeshCache.FillAddColors(mesh_data.AddColors);
mesh.SetUVs(1, GeneratedMeshCache.AddColors);
GeneratedMeshCache.FillMulColors(mesh_data.MulColors);
mesh.SetColors(GeneratedMeshCache.MulColors);
}
}
//
//
//
static class GeneratedMeshCache {
const int PreallocatedVertices = 500;
public static List<int> Indices = new List<int>(PreallocatedVertices * 6 / 4);
public static void FillTriangles(int start_vertex, int index_count) {
Indices.Clear();
if ( Indices.Capacity < index_count ) {
Indices.Capacity = index_count * 2;
}
for ( var i = 0; i < index_count; i += 6 ) {
Indices.Add(start_vertex + 2);
Indices.Add(start_vertex + 1);
Indices.Add(start_vertex + 0);
Indices.Add(start_vertex + 0);
Indices.Add(start_vertex + 3);
Indices.Add(start_vertex + 2);
start_vertex += 4;
}
}
static Vector3 Vertex = Vector3.zero;
public static List<Vector3> Vertices = new List<Vector3>(PreallocatedVertices);
public static void FillVertices(Vector2[] vertices) {
Vertices.Clear();
if ( Vertices.Capacity < vertices.Length ) {
Vertices.Capacity = vertices.Length * 2;
}
for ( int i = 0, e = vertices.Length; i < e; ++i ) {
var vert = vertices[i];
Vertex.x = vert.x;
Vertex.y = vert.y;
Vertices.Add(Vertex);
}
}
static Vector2 UV0 = Vector2.zero;
static Vector2 UV1 = Vector2.zero;
static Vector2 UV2 = Vector2.zero;
static Vector2 UV3 = Vector2.zero;
public static List<Vector2> UVs = new List<Vector2>(PreallocatedVertices);
public static void FillUVs(uint[] uvs) {
UVs.Clear();
if ( UVs.Capacity < uvs.Length * 2 ) {
UVs.Capacity = uvs.Length * 2 * 2;
}
for ( int i = 0, e = uvs.Length; i < e; i += 2 ) {
float min_x, min_y, max_x, max_y;
UnpackUV(uvs[i+0], out min_x, out min_y);
UnpackUV(uvs[i+1], out max_x, out max_y);
UV0.x = min_x; UV0.y = min_y;
UV1.x = max_x; UV1.y = min_y;
UV2.x = max_x; UV2.y = max_y;
UV3.x = min_x; UV3.y = max_y;
UVs.Add(UV0);
UVs.Add(UV1);
UVs.Add(UV2);
UVs.Add(UV3);
}
}
static Vector4 AddColor = Vector4.one;
public static List<Vector4> AddColors = new List<Vector4>(PreallocatedVertices);
public static void FillAddColors(uint[] colors) {
AddColors.Clear();
if ( AddColors.Capacity < colors.Length * 2 ) {
AddColors.Capacity = colors.Length * 2 * 2;
}
for ( int i = 0, e = colors.Length; i < e; i += 2 ) {
UnpackFColorFromUInts(
colors[i+0], colors[i+1],
out AddColor.x, out AddColor.y,
out AddColor.z, out AddColor.w);
AddColors.Add(AddColor);
AddColors.Add(AddColor);
AddColors.Add(AddColor);
AddColors.Add(AddColor);
}
}
static Color MulColor = Color.white;
public static List<Color> MulColors = new List<Color>(PreallocatedVertices);
public static void FillMulColors(uint[] colors) {
MulColors.Clear();
if ( MulColors.Capacity < colors.Length * 2 ) {
MulColors.Capacity = colors.Length * 2 * 2;
}
for ( int i = 0, e = colors.Length; i < e; i += 2 ) {
UnpackFColorFromUInts(
colors[i+0], colors[i+1],
out MulColor.r, out MulColor.g,
out MulColor.b, out MulColor.a);
MulColors.Add(MulColor);
MulColors.Add(MulColor);
MulColors.Add(MulColor);
MulColors.Add(MulColor);
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d367b05a85c4440a1b42bc4311f73004
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using UnityEngine;
using System.Collections.Generic;
namespace FTRuntime {
public class SwfAsset : ScriptableObject {
[System.Serializable]
public struct ConvertingState {
public int Stage;
}
[HideInInspector]
public byte[] Data;
[SwfReadOnly]
public Texture2D Atlas;
[HideInInspector]
public List<SwfClipAsset> Clips;
[HideInInspector]
public SwfSettingsData Settings;
[SwfDisplayName("Settings")]
public SwfSettingsData Overridden;
[HideInInspector]
public ConvertingState Converting;
void Reset() {
Data = new byte[0];
Atlas = null;
Clips = new List<SwfClipAsset>();
Settings = SwfSettingsData.identity;
Overridden = SwfSettingsData.identity;
Converting = new ConvertingState();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9e24daa21915a4a7a914ec3769fa2965
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using UnityEngine;
namespace FTRuntime {
public class SwfIntRangeAttribute : PropertyAttribute {
public int Min;
public int Max;
public SwfIntRangeAttribute(int min, int max) {
Min = min;
Max = max;
}
}
public class SwfFloatRangeAttribute : PropertyAttribute {
public float Min;
public float Max;
public SwfFloatRangeAttribute(float min, float max) {
Min = min;
Max = max;
}
}
public class SwfSortingLayerAttribute : PropertyAttribute {
}
public class SwfPowerOfTwoIfAttribute : PropertyAttribute {
public int MinPow2;
public int MaxPow2;
public string BoolProp;
public SwfPowerOfTwoIfAttribute(int min_pow2, int max_pow2, string bool_prop) {
MinPow2 = min_pow2;
MaxPow2 = max_pow2;
BoolProp = bool_prop;
}
}
public class SwfReadOnlyAttribute : PropertyAttribute {
}
public class SwfDisplayNameAttribute : PropertyAttribute {
public string DisplayName;
public SwfDisplayNameAttribute(string display_name) {
DisplayName = display_name;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b3fa001b52a7246a3b3fb0083c344418
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,347 @@
using UnityEngine;
using FTRuntime.Internal;
namespace FTRuntime {
[ExecuteInEditMode, DisallowMultipleComponent]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SwfClip : MonoBehaviour {
MeshFilter _meshFilter = null;
MeshRenderer _meshRenderer = null;
bool _dirtyMesh = true;
SwfClipAsset.Sequence _curSequence = null;
MaterialPropertyBlock _curPropBlock = null;
// ---------------------------------------------------------------------
//
// Serialized fields
//
// ---------------------------------------------------------------------
[Header("Sorting")]
[SerializeField, SwfSortingLayer]
string _sortingLayer = string.Empty;
[SerializeField]
int _sortingOrder = 0;
[Header("Animation")]
[SerializeField]
Color _tint = Color.white;
[SerializeField]
SwfClipAsset _clip = null;
[SerializeField, HideInInspector]
string _sequence = string.Empty;
[SerializeField, HideInInspector]
int _currentFrame = 0;
// ---------------------------------------------------------------------
//
// Properties
//
// ---------------------------------------------------------------------
/// <summary>
/// Gets or sets the animation mesh renderer sorting layer
/// </summary>
/// <value>The sorting layer</value>
public string sortingLayer {
get { return _sortingLayer; }
set {
_sortingLayer = value;
ChangeSortingProperties();
}
}
/// <summary>
/// Gets or sets the animation mesh renderer sorting order
/// </summary>
/// <value>The sorting order</value>
public int sortingOrder {
get { return _sortingOrder; }
set {
_sortingOrder = value;
ChangeSortingProperties();
}
}
/// <summary>
/// Gets or sets the animation tint color
/// </summary>
/// <value>The tint color</value>
public Color tint {
get { return _tint; }
set {
_tint = value;
ChangeTint();
}
}
/// <summary>
/// Gets or sets the animation asset (reset sequence and current frame)
/// </summary>
/// <value>The animation asset</value>
public SwfClipAsset clip {
get { return _clip; }
set {
_clip = value;
_sequence = string.Empty;
_currentFrame = 0;
ChangeClip();
}
}
/// <summary>
/// Gets or sets the animation sequence (reset current frame)
/// </summary>
/// <value>The animation sequence</value>
public string sequence {
get { return _sequence; }
set {
_sequence = value;
_currentFrame = 0;
ChangeSequence();
}
}
/// <summary>
/// Gets or sets the animation current frame
/// </summary>
/// <value>The animation current frame</value>
public int currentFrame {
get { return _currentFrame; }
set {
_currentFrame = value;
ChangeCurrentFrame();
}
}
/// <summary>
/// Gets the current animation sequence frame count
/// </summary>
/// <value>The frame count.</value>
public int frameCount {
get {
return _curSequence != null && _curSequence.Frames != null
? _curSequence.Frames.Count
: 0;
}
}
/// <summary>
/// Gets the animation frame rate
/// </summary>
/// <value>The frame rate.</value>
public float frameRate {
get {
return clip
? clip.FrameRate
: 1.0f;
}
}
// ---------------------------------------------------------------------
//
// Functions
//
// ---------------------------------------------------------------------
/// <summary>
/// Rewind current sequence to begin frame
/// </summary>
public void ToBeginFrame() {
currentFrame = 0;
}
/// <summary>
/// Rewind current sequence to end frame
/// </summary>
public void ToEndFrame() {
currentFrame = frameCount > 0
? frameCount - 1
: 0;
}
/// <summary>
/// Rewind current sequence to previous frame
/// </summary>
/// <returns><c>true</c>, if animation was rewound, <c>false</c> otherwise.</returns>
public bool ToPrevFrame() {
if ( currentFrame > 0 ) {
--currentFrame;
return true;
}
return false;
}
/// <summary>
/// Rewind current sequence to next frame
/// </summary>
/// <returns><c>true</c>, if animation was rewound, <c>false</c> otherwise.</returns>
public bool ToNextFrame() {
if ( currentFrame < frameCount - 1 ) {
++currentFrame;
return true;
}
return false;
}
// ---------------------------------------------------------------------
//
// Internal
//
// ---------------------------------------------------------------------
internal void Internal_LateUpdate() {
if ( _meshFilter && _meshRenderer && _dirtyMesh ) {
var baked_frame = GetCurrentBakedFrame();
if ( baked_frame != null ) {
_meshFilter .sharedMesh = baked_frame.CachedMesh;
_meshRenderer.sharedMaterials = baked_frame.Materials;
} else {
_meshFilter .sharedMesh = null;
_meshRenderer.sharedMaterials = new Material[0];
}
_dirtyMesh = false;
}
}
/// <summary>
/// Update all animation properties (for internal use only)
/// </summary>
public void Internal_UpdateAllProperties() {
ClearCache();
ChangeTint();
ChangeClip();
ChangeSequence();
ChangeCurrentFrame();
ChangeSortingProperties();
}
void ClearCache() {
_meshFilter = GetComponent<MeshFilter>();
_meshRenderer = GetComponent<MeshRenderer>();
_dirtyMesh = true;
_curSequence = null;
_curPropBlock = null;
}
void ChangeTint() {
UpdatePropBlock();
}
void ChangeClip() {
if ( _meshRenderer ) {
_meshRenderer.enabled = !!clip;
}
ChangeSequence();
UpdatePropBlock();
}
void ChangeSequence() {
_curSequence = null;
if ( clip && clip.Sequences != null ) {
if ( !string.IsNullOrEmpty(sequence) ) {
for ( int i = 0, e = clip.Sequences.Count; i < e; ++i ) {
var clip_sequence = clip.Sequences[i];
if ( clip_sequence != null && clip_sequence.Name == sequence ) {
_curSequence = clip_sequence;
break;
}
}
if ( _curSequence == null ) {
Debug.LogWarningFormat(this,
"<b>[FlashTools]</b> Sequence '{0}' not found",
sequence);
}
}
if ( _curSequence == null ) {
for ( int i = 0, e = clip.Sequences.Count; i < e; ++i ) {
var clip_sequence = clip.Sequences[i];
if ( clip_sequence != null ) {
_sequence = clip_sequence.Name;
_curSequence = clip_sequence;
break;
}
}
}
}
ChangeCurrentFrame();
}
void ChangeCurrentFrame() {
_dirtyMesh = true;
_currentFrame = frameCount > 0
? Mathf.Clamp(currentFrame, 0, frameCount - 1)
: 0;
}
void ChangeSortingProperties() {
if ( _meshRenderer ) {
_meshRenderer.sortingOrder = sortingOrder;
_meshRenderer.sortingLayerName = sortingLayer;
}
}
void UpdatePropBlock() {
if ( _meshRenderer ) {
if ( _curPropBlock == null ) {
_curPropBlock = new MaterialPropertyBlock();
}
_meshRenderer.GetPropertyBlock(_curPropBlock);
_curPropBlock.SetColor(
"_Tint",
tint);
_curPropBlock.SetTexture(
"_MainTex",
clip && clip.Atlas ? clip.Atlas : Texture2D.whiteTexture);
_meshRenderer.SetPropertyBlock(_curPropBlock);
}
}
SwfClipAsset.Frame GetCurrentBakedFrame() {
var frames = _curSequence != null ? _curSequence.Frames : null;
return frames != null && currentFrame >= 0 && currentFrame < frames.Count
? frames[currentFrame]
: null;
}
// ---------------------------------------------------------------------
//
// Messages
//
// ---------------------------------------------------------------------
void Awake() {
Internal_UpdateAllProperties();
}
void OnEnable() {
var swf_manager = SwfManager.GetInstance(true);
if ( swf_manager ) {
swf_manager.AddClip(this);
}
}
void OnDisable() {
var swf_manager = SwfManager.GetInstance(false);
if ( swf_manager ) {
swf_manager.RemoveClip(this);
}
}
void Reset() {
Internal_UpdateAllProperties();
}
void OnValidate() {
Internal_UpdateAllProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d720f6c1045ab4d45b705672aba45e73
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using UnityEngine;
using FTRuntime.Internal;
using System.Collections.Generic;
namespace FTRuntime {
public class SwfClipAsset : ScriptableObject {
[System.Serializable]
public class SubMeshData {
public int StartVertex;
public int IndexCount;
}
[System.Serializable]
public class MeshData {
public SubMeshData[] SubMeshes = new SubMeshData[0];
public Vector2[] Vertices = new Vector2[0];
public uint[] UVs = new uint[0];
public uint[] AddColors = new uint[0];
public uint[] MulColors = new uint[0];
}
[System.Serializable]
public class Frame {
public MeshData MeshData = new MeshData();
public Material[] Materials = new Material[0];
public Frame() {
MeshData = new MeshData();
Materials = new Material[0];
}
public Frame(MeshData mesh_data, Material[] materials) {
MeshData = mesh_data;
Materials = materials;
}
Mesh _cachedMesh = null;
public Mesh CachedMesh {
get {
if ( !_cachedMesh ) {
_cachedMesh = new Mesh();
SwfUtils.FillGeneratedMesh(_cachedMesh, MeshData);
}
return _cachedMesh;
}
}
}
[System.Serializable]
public class Sequence {
public string Name = string.Empty;
public List<Frame> Frames = new List<Frame>();
}
[SwfReadOnly]
public string Name;
[SwfReadOnly]
public Texture2D Atlas;
[SwfReadOnly]
public float FrameRate;
[HideInInspector]
public List<Sequence> Sequences;
void Reset() {
Name = string.Empty;
Atlas = null;
FrameRate = 1.0f;
Sequences = new List<Sequence>();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0c9fa30e000f3420796cfbd1e09a86d6
timeCreated: 1480698333
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,371 @@
using UnityEngine;
using FTRuntime.Internal;
namespace FTRuntime {
[ExecuteInEditMode, DisallowMultipleComponent]
[RequireComponent(typeof(SwfClip))]
public class SwfClipController : MonoBehaviour {
SwfClip _clip = null;
bool _isPlaying = false;
float _tickTimer = 0.0f;
// ---------------------------------------------------------------------
//
// Events
//
// ---------------------------------------------------------------------
/// <summary>
/// Occurs when on stop playing event
/// </summary>
public event System.Action<SwfClipController> OnStopPlayingEvent;
/// <summary>
/// Occurs when on play stopped event
/// </summary>
public event System.Action<SwfClipController> OnPlayStoppedEvent;
/// <summary>
/// Occurs when on rewind playing event
/// </summary>
public event System.Action<SwfClipController> OnRewindPlayingEvent;
// ---------------------------------------------------------------------
//
// Serialized fields
//
// ---------------------------------------------------------------------
[SerializeField]
bool _autoPlay = true;
[SerializeField, SwfFloatRange(0.0f, float.MaxValue)]
float _rateScale = 1.0f;
[SerializeField]
string _groupName = string.Empty;
[SerializeField]
PlayModes _playMode = PlayModes.Forward;
[SerializeField]
LoopModes _loopMode = LoopModes.Loop;
// ---------------------------------------------------------------------
//
// Properties
//
// ---------------------------------------------------------------------
/// <summary>
/// Controller play modes
/// </summary>
public enum PlayModes {
/// <summary>
/// Forward play mode
/// </summary>
Forward,
/// <summary>
/// Backward play mode
/// </summary>
Backward
}
/// <summary>
/// Controller loop modes
/// </summary>
public enum LoopModes {
/// <summary>
/// Once loop mode
/// </summary>
Once,
/// <summary>
/// Repeat loop mode
/// </summary>
Loop
}
/// <summary>
/// Gets or sets a value indicating whether controller play after awake on scene
/// </summary>
/// <value><c>true</c> if auto play; otherwise, <c>false</c></value>
public bool autoPlay {
get { return _autoPlay; }
set { _autoPlay = value; }
}
/// <summary>
/// Gets or sets the controller rate scale
/// </summary>
/// <value>The rate scale</value>
public float rateScale {
get { return _rateScale; }
set { _rateScale = Mathf.Clamp(value, 0.0f, float.MaxValue); }
}
/// <summary>
/// Gets or sets the controller group name
/// </summary>
/// <value>The group name</value>
public string groupName {
get { return _groupName; }
set { _groupName = value; }
}
/// <summary>
/// Gets or sets the controller play mode
/// </summary>
/// <value>The play mode</value>
public PlayModes playMode {
get { return _playMode; }
set { _playMode = value; }
}
/// <summary>
/// Gets or sets the controller loop mode
/// </summary>
/// <value>The loop mode</value>
public LoopModes loopMode {
get { return _loopMode; }
set { _loopMode = value; }
}
/// <summary>
/// Gets the controller clip
/// </summary>
/// <value>The clip</value>
public SwfClip clip {
get { return _clip; }
}
/// <summary>
/// Gets a value indicating whether controller is playing
/// </summary>
/// <value><c>true</c> if is playing; otherwise, <c>false</c></value>
public bool isPlaying {
get { return _isPlaying; }
}
/// <summary>
/// Gets a value indicating whether controller is stopped
/// </summary>
/// <value><c>true</c> if is stopped; otherwise, <c>false</c></value>
public bool isStopped {
get { return !_isPlaying; }
}
// ---------------------------------------------------------------------
//
// Functions
//
// ---------------------------------------------------------------------
/// <summary>
/// Changes the animation frame with stops it
/// </summary>
/// <param name="frame">The new current frame</param>
public void GotoAndStop(int frame) {
if ( clip ) {
clip.currentFrame = frame;
}
Stop(false);
}
/// <summary>
/// Changes the animation sequence and frame with stops it
/// </summary>
/// <param name="sequence">The new sequence</param>
/// <param name="frame">The new current frame</param>
public void GotoAndStop(string sequence, int frame) {
if ( clip ) {
clip.sequence = sequence;
}
GotoAndStop(frame);
}
/// <summary>
/// Changes the animation frame with plays it
/// </summary>
/// <param name="frame">The new current frame</param>
public void GotoAndPlay(int frame) {
if ( clip ) {
clip.currentFrame = frame;
}
Play(false);
}
/// <summary>
/// Changes the animation sequence and frame with plays it
/// </summary>
/// <param name="sequence">The new sequence</param>
/// <param name="frame">The new current frame</param>
public void GotoAndPlay(string sequence, int frame) {
if ( clip ) {
clip.sequence = sequence;
}
GotoAndPlay(frame);
}
/// <summary>
/// Stop with specified rewind action
/// </summary>
/// <param name="rewind">If set to <c>true</c> rewind animation to begin frame</param>
public void Stop(bool rewind) {
var is_playing = isPlaying;
if ( is_playing ) {
_isPlaying = false;
_tickTimer = 0.0f;
}
if ( rewind ) {
Rewind();
}
if ( is_playing && OnStopPlayingEvent != null ) {
OnStopPlayingEvent(this);
}
}
/// <summary>
/// Changes the animation sequence and stop controller with rewind
/// </summary>
/// <param name="sequence">The new sequence</param>
public void Stop(string sequence) {
if ( clip ) {
clip.sequence = sequence;
}
Stop(true);
}
/// <summary>
/// Play with specified rewind action
/// </summary>
/// <param name="rewind">If set to <c>true</c> rewind animation to begin frame</param>
public void Play(bool rewind) {
var is_stopped = isStopped;
if ( is_stopped ) {
_isPlaying = true;
_tickTimer = 0.0f;
}
if ( rewind ) {
Rewind();
}
if ( is_stopped && OnPlayStoppedEvent != null ) {
OnPlayStoppedEvent(this);
}
}
/// <summary>
/// Changes the animation sequence and play controller with rewind
/// </summary>
/// <param name="sequence">The new sequence</param>
public void Play(string sequence) {
if ( clip ) {
clip.sequence = sequence;
}
Play(true);
}
/// <summary>
/// Rewind animation to begin frame
/// </summary>
public void Rewind() {
switch ( playMode ) {
case PlayModes.Forward:
if ( clip ) {
clip.ToBeginFrame();
}
break;
case PlayModes.Backward:
if ( clip ) {
clip.ToEndFrame();
}
break;
default:
throw new UnityException(string.Format(
"SwfClipController. Incorrect play mode: {0}",
playMode));
}
if ( isPlaying && OnRewindPlayingEvent != null ) {
OnRewindPlayingEvent(this);
}
}
// ---------------------------------------------------------------------
//
// Internal
//
// ---------------------------------------------------------------------
internal void Internal_Update(float dt) {
if ( isPlaying ) {
UpdateTimer(dt);
}
}
void UpdateTimer(float dt) {
var frame_rate = clip ? clip.frameRate : 1.0f;
_tickTimer += frame_rate * rateScale * dt;
while ( _tickTimer > 1.0f ) {
_tickTimer -= 1.0f;
TimerTick();
}
}
void TimerTick() {
if ( !NextClipFrame() ) {
switch ( loopMode ) {
case LoopModes.Once:
Stop(false);
break;
case LoopModes.Loop:
Rewind();
break;
default:
throw new UnityException(string.Format(
"SwfClipController. Incorrect loop mode: {0}",
loopMode));
}
}
}
bool NextClipFrame() {
switch ( playMode ) {
case PlayModes.Forward:
return clip ? clip.ToNextFrame() : false;
case PlayModes.Backward:
return clip ? clip.ToPrevFrame() : false;
default:
throw new UnityException(string.Format(
"SwfClipController. Incorrect play mode: {0}",
playMode));
}
}
// ---------------------------------------------------------------------
//
// Messages
//
// ---------------------------------------------------------------------
void Awake() {
_clip = GetComponent<SwfClip>();
if ( autoPlay && Application.isPlaying ) {
Play(false);
}
}
void OnEnable() {
var swf_manager = SwfManager.GetInstance(true);
if ( swf_manager ) {
swf_manager.AddController(this);
}
}
void OnDisable() {
var swf_manager = SwfManager.GetInstance(false);
if ( swf_manager ) {
swf_manager.RemoveController(this);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 92ca98b80846d4b34b476a918b98a542
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,279 @@
using UnityEngine;
using FTRuntime.Internal;
using System.Collections.Generic;
namespace FTRuntime {
[ExecuteInEditMode, DisallowMultipleComponent]
public class SwfManager : MonoBehaviour {
SwfAssocList<SwfClip> _clips = new SwfAssocList<SwfClip>();
SwfAssocList<SwfClipController> _controllers = new SwfAssocList<SwfClipController>();
SwfList<SwfClipController> _safeUpdates = new SwfList<SwfClipController>();
bool _isPaused = false;
float _rateScale = 1.0f;
HashSet<string> _groupPauses = new HashSet<string>();
Dictionary<string, float> _groupRateScales = new Dictionary<string, float>();
// ---------------------------------------------------------------------
//
// Instance
//
// ---------------------------------------------------------------------
static SwfManager _instance;
/// <summary>
/// Get cached manager instance from scene or create it (if allowed)
/// </summary>
/// <returns>The manager instance</returns>
/// <param name="allow_create">If set to <c>true</c> allow create</param>
public static SwfManager GetInstance(bool allow_create) {
if ( !_instance ) {
_instance = FindObjectOfType<SwfManager>();
if ( allow_create && !_instance ) {
var go = new GameObject("[SwfManager]");
_instance = go.AddComponent<SwfManager>();
}
}
return _instance;
}
// ---------------------------------------------------------------------
//
// Properties
//
// ---------------------------------------------------------------------
/// <summary>
/// Get animation clip count on scene
/// </summary>
/// <value>Clip count</value>
public int clipCount {
get { return _clips.Count; }
}
/// <summary>
/// Get animation clip controller count on scene
/// </summary>
/// <value>Clip controller count</value>
public int controllerCount {
get { return _controllers.Count; }
}
/// <summary>
/// Get or set a value indicating whether animation updates is paused
/// </summary>
/// <value><c>true</c> if is paused; otherwise, <c>false</c>.</value>
public bool isPaused {
get { return _isPaused; }
set { _isPaused = value; }
}
/// <summary>
/// Get or set a value indicating whether animation updates is playing
/// </summary>
/// <value><c>true</c> if is playing; otherwise, <c>false</c>.</value>
public bool isPlaying {
get { return !_isPaused; }
set { _isPaused = !value; }
}
/// <summary>
/// Get or set the global animation rate scale
/// </summary>
/// <value>Global rate scale</value>
public float rateScale {
get { return _rateScale; }
set { _rateScale = Mathf.Clamp(value, 0.0f, float.MaxValue); }
}
// ---------------------------------------------------------------------
//
// Functions
//
// ---------------------------------------------------------------------
/// <summary>
/// Pause animation updates
/// </summary>
public void Pause() {
isPaused = true;
}
/// <summary>
/// Resume animation updates
/// </summary>
public void Resume() {
isPlaying = true;
}
/// <summary>
/// Pause the group of animations by name
/// </summary>
/// <param name="group_name">Group name</param>
public void PauseGroup(string group_name) {
if ( !string.IsNullOrEmpty(group_name) ) {
_groupPauses.Add(group_name);
}
}
/// <summary>
/// Resume the group of animations by name
/// </summary>
/// <param name="group_name">Group name</param>
public void ResumeGroup(string group_name) {
if ( !string.IsNullOrEmpty(group_name) ) {
_groupPauses.Remove(group_name);
}
}
/// <summary>
/// Determines whether group of animations is paused
/// </summary>
/// <returns><c>true</c> if group is paused; otherwise, <c>false</c>.</returns>
/// <param name="group_name">Group name</param>
public bool IsGroupPaused(string group_name) {
return _groupPauses.Contains(group_name);
}
/// <summary>
/// Determines whether group of animations is playing
/// </summary>
/// <returns><c>true</c> if group is playing; otherwise, <c>false</c>.</returns>
/// <param name="group_name">Group name</param>
public bool IsGroupPlaying(string group_name) {
return !IsGroupPaused(group_name);
}
/// <summary>
/// Set the group of animations rate scale
/// </summary>
/// <param name="group_name">Group name</param>
/// <param name="rate_scale">Rate scale</param>
public void SetGroupRateScale(string group_name, float rate_scale) {
if ( !string.IsNullOrEmpty(group_name) ) {
_groupRateScales[group_name] = Mathf.Clamp(rate_scale, 0.0f, float.MaxValue);
}
}
/// <summary>
/// Get the group of animations rate scale
/// </summary>
/// <returns>The group rate scale.</returns>
/// <param name="group_name">Group name.</param>
public float GetGroupRateScale(string group_name) {
float rate_scale;
return _groupRateScales.TryGetValue(group_name, out rate_scale)
? rate_scale
: 1.0f;
}
// ---------------------------------------------------------------------
//
// Internal
//
// ---------------------------------------------------------------------
internal void AddClip(SwfClip clip) {
_clips.Add(clip);
}
internal void RemoveClip(SwfClip clip) {
_clips.Remove(clip);
}
internal void GetAllClips(List<SwfClip> clips) {
_clips.AssignTo(clips);
}
internal void AddController(SwfClipController controller) {
_controllers.Add(controller);
}
internal void RemoveController(SwfClipController controller) {
_controllers.Remove(controller);
}
void GrabEnabledClips() {
var clips = FindObjectsOfType<SwfClip>();
for ( int i = 0, e = clips.Length; i < e; ++i ) {
var clip = clips[i];
if ( clip.enabled ) {
_clips.Add(clip);
}
}
}
void GrabEnabledControllers() {
var controllers = FindObjectsOfType<SwfClipController>();
for ( int i = 0, e = controllers.Length; i < e; ++i ) {
var controller = controllers[i];
if ( controller.enabled ) {
_controllers.Add(controller);
}
}
}
void DropClips() {
_clips.Clear();
}
void DropControllers() {
_controllers.Clear();
}
void UpdateControllers(float dt) {
_controllers.AssignTo(_safeUpdates);
for ( int i = 0, e = _safeUpdates.Count; i < e; ++i ) {
var ctrl = _safeUpdates[i];
if ( ctrl ) {
var group_name = ctrl.groupName;
if ( string.IsNullOrEmpty(group_name) ) {
ctrl.Internal_Update(dt);
} else if ( IsGroupPlaying(group_name) ) {
var group_rate_scale = GetGroupRateScale(group_name);
ctrl.Internal_Update(group_rate_scale * dt);
}
}
}
_safeUpdates.Clear();
}
void LateUpdateClips() {
for ( int i = 0, e = _clips.Count; i < e; ++i ) {
var clip = _clips[i];
if ( clip ) {
clip.Internal_LateUpdate();
}
}
}
// ---------------------------------------------------------------------
//
// Messages
//
// ---------------------------------------------------------------------
void OnEnable() {
GrabEnabledClips();
GrabEnabledControllers();
}
void OnDisable() {
DropClips();
DropControllers();
}
void Update() {
if ( isPlaying ) {
var dt = Time.deltaTime;
UpdateControllers(rateScale * dt);
}
}
void LateUpdate() {
LateUpdateClips();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f455e092ebcb64c3e94de2e2f2f7a614
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using UnityEngine;
namespace FTRuntime {
[System.Serializable]
public struct SwfSettingsData {
public enum AtlasFilter {
Point,
Bilinear,
Trilinear
}
public enum AtlasFormat {
AutomaticCompressed,
Automatic16bit,
AutomaticTruecolor,
AutomaticCrunched
}
[SwfPowerOfTwoIfAttribute(5, 13, "AtlasPowerOfTwo")]
public int MaxAtlasSize;
[SwfIntRange(0, int.MaxValue)]
public int AtlasPadding;
[SwfFloatRange(float.Epsilon, float.MaxValue)]
public float PixelsPerUnit;
public bool GenerateMipMaps;
public bool AtlasPowerOfTwo;
public bool AtlasForceSquare;
public AtlasFilter AtlasTextureFilter;
public AtlasFormat AtlasTextureFormat;
public static SwfSettingsData identity {
get {
return new SwfSettingsData{
MaxAtlasSize = 1024,
AtlasPadding = 1,
PixelsPerUnit = 100.0f,
GenerateMipMaps = false,
AtlasPowerOfTwo = true,
AtlasForceSquare = true,
AtlasTextureFilter = AtlasFilter.Bilinear,
AtlasTextureFormat = AtlasFormat.AutomaticCompressed};
}
}
public bool CheckEquals(SwfSettingsData other) {
return
MaxAtlasSize == other.MaxAtlasSize &&
AtlasPadding == other.AtlasPadding &&
Mathf.Approximately(PixelsPerUnit, other.PixelsPerUnit) &&
GenerateMipMaps == other.GenerateMipMaps &&
AtlasPowerOfTwo == other.AtlasPowerOfTwo &&
AtlasForceSquare == other.AtlasForceSquare &&
AtlasTextureFilter == other.AtlasTextureFilter &&
AtlasTextureFormat == other.AtlasTextureFormat;
}
}
public class SwfSettings : ScriptableObject {
public SwfSettingsData Settings;
void Reset() {
Settings = SwfSettingsData.identity;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cf7a304f962ab44789f4fb85ff562e2a
timeCreated: 1480698334
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: