using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Text.RegularExpressions; using UnityEngine; using Cryville.Common; using Cryville.Common.Plist; namespace Cryville.Crtr { [BinderAttribute(typeof(Cocos2dFramesBinder))] public class Cocos2dFrames { public Metadata metadata; public class Metadata { public int format; public Vector2 size; public string textureFileName; } public Dictionary frames; public class Frame { Rect _frame; public Rect frame { get { return _frame; } set { _frame = value; } } public Rect textureRect { get { return _frame; } set { _frame = value; } } public Vector2 offset; bool _rotated = false; public bool rotated { get { return _rotated; } set { _rotated = value; } } public bool textureRotated { get { return _rotated; } set { _rotated = value; } } public Rect sourceColorRect; public Vector2 sourceSize; private Rect _uv; private Vector2[] cuv; public Rect UV { get { return _uv; } private set { _uv = value; float x0 = Mathf.Min(_uv.xMin, _uv.xMax); float x1 = Mathf.Max(_uv.xMin, _uv.xMax); float y0 = Mathf.Min(_uv.yMin, _uv.yMax); float y1 = Mathf.Max(_uv.yMin, _uv.yMax); if (_rotated) cuv = new Vector2[]{ new Vector2(x0, y1), new Vector2(x1, y0), new Vector2(x0, y0), new Vector2(x1, y1), }; else cuv = new Vector2[]{ new Vector2(x0, y0), new Vector2(x1, y1), new Vector2(x1, y0), new Vector2(x0, y1), }; } } public Vector2 GetUV(Vector2 uv) { return GetUV(uv.x, uv.y); } public Vector2 GetUV(float u, float v) { Vector2 uv00 = cuv[0], uv11 = cuv[1], uv10 = cuv[2], uv01 = cuv[3]; return (1 - u - v) * uv00 + u * uv10 + v * uv01 + u * v * (uv00 + uv11 - uv10 - uv01); } public Texture2D Texture { get; private set; } public Vector2 Size { get { return new Vector2(Texture.width, Texture.height); } } public void Init() { if (Texture == null) throw new InvalidOperationException(); // TODO _frame = new Rect(Vector2.zero, Size); var w = _frame.width; var h = _frame.height; float x = _frame.x / w; float y = 1 - _frame.y / h; float tw = (_rotated ? _frame.height : _frame.width) / w; float th = (_rotated ? _frame.width : _frame.height) / h; if (_rotated) UV = new Rect(x, y, tw, -th); else UV = new Rect(x, y, tw, -th); } public void Init(int w, int h, Texture2D _base) { if (Texture != null) throw new InvalidOperationException(); // TODO Texture = _base; float x = _frame.x / w; float y = 1 - _frame.y / h; float tw = (_rotated ? _frame.height : _frame.width) / w; float th = (_rotated ? _frame.width : _frame.height) / h; if (_rotated) UV = new Rect(x, y, tw, -th); else UV = new Rect(x, y, tw, -th); } public Frame() { } public Frame(Texture2D tex) { Texture = tex; } } Texture2D _base; public void Init(Dictionary texs) { _base = texs[StringUtils.TrimExt(metadata.textureFileName)]; var w = (int)metadata.size.x; var h = (int)metadata.size.y; if (w == 0 || h == 0) { w = _base.width; h = _base.height; } foreach (var f in frames) { f.Value.Init(w, h, _base); } } } public class Cocos2dFramesBinder : EmptyBinder { public override object ChangeType(object value, Type type, CultureInfo culture) { if (value is string) { var str = (string)value; if (type == typeof(Rect)) { var m = Regex.Match(str, @"^{({.*?}),({.*?})}$"); var p = (Vector2)ChangeType(m.Groups[1].Value, typeof(Vector2), culture); var s = (Vector2)ChangeType(m.Groups[2].Value, typeof(Vector2), culture); return new Rect(p, s); } else if (type == typeof(Vector2)) { var m = Regex.Match(str, @"^{(.*?),(.*?)}$"); var w = float.Parse(m.Groups[1].Value); var h = float.Parse(m.Groups[2].Value); return new Vector2(w, h); } } else if (typeof(IDictionary).IsAssignableFrom(value.GetType())) { var dict = (IDictionary)value; if (type == typeof(Rect)) { var x = float.Parse((string)dict["x"]); var y = float.Parse((string)dict["y"]); var w = float.Parse((string)dict["w"]); var h = float.Parse((string)dict["h"]); return new Rect(x, y, w, h); } else if (type == typeof(Vector2)) { var w = float.Parse((string)dict["w"]); var h = float.Parse((string)dict["h"]); return new Vector2(w, h); } } return base.ChangeType(value, type, culture); } } }