177 lines
4.7 KiB
C#
177 lines
4.7 KiB
C#
using Cryville.Common;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Text.RegularExpressions;
|
|
using UnityEngine;
|
|
|
|
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<string, Frame> frames;
|
|
public class Frame {
|
|
#pragma warning disable IDE1006
|
|
Rect _frame;
|
|
public Rect frame {
|
|
get { return _frame; }
|
|
set { _frame = value; }
|
|
}
|
|
public Rect textureRect {
|
|
get { return _frame; }
|
|
set { _frame = value; }
|
|
}
|
|
|
|
bool _rotated = false;
|
|
public bool rotated {
|
|
get { return _rotated; }
|
|
set { _rotated = value; }
|
|
}
|
|
public bool textureRotated {
|
|
get { return _rotated; }
|
|
set { _rotated = value; }
|
|
}
|
|
#pragma warning restore IDE1006
|
|
|
|
public Vector2 offset;
|
|
|
|
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<string, Texture2D> 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);
|
|
}
|
|
}
|
|
}
|