AvatarDollStruct.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. using Godot;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text.Json.Serialization;
  5. namespace AvatarDoll
  6. {
  7. /// <summary>
  8. /// Avatar作者的元信息
  9. /// </summary>
  10. [Serializable]
  11. public struct Metadata
  12. {
  13. [JsonInclude] public string Author { get; set; }
  14. [JsonInclude] public string Introduction { get; set; }
  15. [JsonInclude] public string Version { get; set; }
  16. [JsonInclude] public string Link { get; set; }
  17. }
  18. [Serializable]
  19. public struct PartState
  20. {
  21. public PartState() { }
  22. [JsonInclude] public string Name { get; set; } = "";
  23. [JsonInclude] public PartScope Scope { get; set; } = 0;
  24. [JsonInclude] public byte Default { get; set; } = 0;
  25. [JsonInclude] public List<string> Values { get; set; } = new();
  26. [JsonInclude] public List<bool> Required { get; set; } = new();
  27. public override bool Equals(object obj)
  28. {
  29. return obj is PartState state && Equals(state);
  30. }
  31. public bool Equals(PartState other)
  32. {
  33. return Name == other.Name &&
  34. Scope == other.Scope &&
  35. Default == other.Default &&
  36. System.Linq.Enumerable.SequenceEqual(Values, other.Values) &&
  37. System.Linq.Enumerable.SequenceEqual(Required, other.Required);
  38. }
  39. }
  40. /// <summary>
  41. /// Avatar配置项
  42. /// </summary>
  43. [Serializable]
  44. public struct ProjectSettings
  45. {
  46. public ProjectSettings() { }
  47. [JsonInclude] public int MaxBodySlotCost { get; set; } = 5;
  48. [JsonInclude] public List<PartState> States { get; set; } = new();
  49. public static int GetStatusesCode(ProjectSettings settings)
  50. {
  51. int finalHash = 0;
  52. foreach (var state in settings.States)
  53. {
  54. int listHash = 0;
  55. foreach (var value in state.Required)
  56. {
  57. int valueHash = value ? 1 : 0;
  58. listHash = CombineHashes(listHash, valueHash);
  59. }
  60. finalHash = CombineHashes(finalHash, listHash);
  61. }
  62. return finalHash;
  63. }
  64. private static int CombineHashes(int h1, int h2)
  65. {
  66. long hash = 2166136261L;
  67. hash = (hash ^ (h1 & 0xFF)) * 16777619;
  68. hash = (hash ^ ((h1 >> 8) & 0xFF)) * 16777619;
  69. hash = (hash ^ ((h1 >> 16) & 0xFF)) * 16777619;
  70. hash = (hash ^ ((h1 >> 24) & 0xFF)) * 16777619;
  71. hash = (hash ^ (h2 & 0xFF)) * 16777619;
  72. hash = (hash ^ ((h2 >> 8) & 0xFF)) * 16777619;
  73. hash = (hash ^ ((h2 >> 16) & 0xFF)) * 16777619;
  74. hash = (hash ^ ((h2 >> 24) & 0xFF)) * 16777619;
  75. return (int)(hash & 0x7FFFFFFF);
  76. }
  77. public override bool Equals(object obj)
  78. {
  79. return obj is ProjectSettings settings && Equals(settings);
  80. }
  81. public bool Equals(ProjectSettings other)
  82. {
  83. bool equal = MaxBodySlotCost == other.MaxBodySlotCost
  84. && States.Count == other.States.Count;
  85. if (equal == false) return false;
  86. for (int i = 0; i < States.Count; i++)
  87. equal &= States[i].Equals(other.States[i]);
  88. return equal;
  89. }
  90. public override int GetHashCode()
  91. {
  92. return GetStatusesCode(this);
  93. }
  94. }
  95. /// <summary>
  96. ///
  97. /// </summary>
  98. [Serializable]
  99. public struct PaletteColor
  100. {
  101. [JsonInclude] public float R { get; set; }
  102. [JsonInclude] public float G { get; set; }
  103. [JsonInclude] public float B { get; set; }
  104. [JsonInclude] public float A { get; set; }
  105. public PaletteColor(float r, float g, float b, float a = 1.0f) { R = r; G = g; B = b; A = a; }
  106. public PaletteColor(Godot.Color color) { R = color.R; G = color.G; B = color.B; A = color.A; }
  107. public static implicit operator Godot.Color(PaletteColor color) { return new Godot.Color(color.R, color.G, color.B, color.A); }
  108. public static implicit operator PaletteColor(Godot.Color color) { return new PaletteColor(color); }
  109. public override bool Equals(object obj)
  110. {
  111. if (obj is PaletteColor other)
  112. {
  113. return (double) this.R == (double) other.R && (double) this.G == (double) other.G && (double) this.B == (double) other.B && (double) this.A == (double) other.A;
  114. }
  115. return false;
  116. }
  117. public override int GetHashCode()
  118. {
  119. return HashCode.Combine(R, G, B, A);
  120. }
  121. }
  122. /// <summary>
  123. /// 图片调色参数
  124. /// </summary>
  125. [Serializable]
  126. public struct PaletteParam()
  127. {
  128. [JsonInclude] public int ElementIndex = -1;
  129. [JsonInclude] public PaletteColor BasicColor { get; set; } = new PaletteColor(0,0,0,0);
  130. [JsonInclude] public int Tolerance = 0;
  131. [JsonInclude] public PaletteColor ModulateColor { get; set; } = new PaletteColor(0,0,0,0);
  132. [JsonInclude] public int BlendMode = 0;
  133. public override bool Equals(object obj)
  134. {
  135. return obj is PaletteParam other && Equals(other);
  136. }
  137. public bool Equals(PaletteParam other)
  138. {
  139. return BasicColor.Equals(other.BasicColor) &&
  140. ModulateColor.Equals(other.ModulateColor) &&
  141. Tolerance == other.Tolerance &&
  142. BlendMode == other.BlendMode;
  143. }
  144. public override int GetHashCode()
  145. {
  146. return HashCode.Combine(ElementIndex, Tolerance, BlendMode, BasicColor.GetHashCode(), ModulateColor.GetHashCode());
  147. }
  148. }
  149. /// <summary>
  150. /// 调色板。用于保存其他上色方案,且可以指定不同配色下的别名
  151. /// </summary>
  152. [Serializable]
  153. public struct Palette()
  154. {
  155. [JsonInclude] public uint Guid { get; set; } = 0;
  156. [JsonInclude] public string Name { get; set; }
  157. [JsonInclude] public string Introduction { get; set; }
  158. [JsonInclude] public List<ThemeColor> ThemeColors { get; set; } = [];
  159. [JsonInclude] public List<PaletteParam> IconPaletteParams { get; set; } = [];
  160. [JsonInclude] public List<PaletteParam> ElementPaletteParams { get; set; } = [];
  161. }
  162. /// <summary>
  163. /// Avatar的某个元素的集合,可以是一个身形,或者一个脸型,一件服装等
  164. /// 例如对于头发,就是一个发型在所有Pose下的样子的集合。脸型、服装等同理
  165. /// </summary>
  166. [Serializable]
  167. public class AvatarPart()
  168. {
  169. [JsonInclude] public uint Guid { get; set; } = 0;
  170. [JsonInclude] public string Name { get; set; }
  171. [JsonInclude] public int IconAssetId { get; set; }
  172. [JsonInclude] public string Introduction { get; set; }
  173. [JsonInclude] public List<ThemeColor> ThemeColors { get; set; } = [];
  174. /// <summary>
  175. /// 调色板。如果该服装有除了默认颜色外的其他上色方案,可以在这里保存
  176. /// </summary>
  177. [JsonInclude] public List<Palette> Palettes { get; set; } = [];
  178. /// <summary>
  179. /// 每个pose的数据
  180. /// key: PoseID
  181. /// value: AvatarPoses是个AvatarPosePart数组。 例如一个装备在站立状态下的pose图可能由多张图片组合而成
  182. /// </summary>
  183. [JsonInclude] public Dictionary<string, List<AvatarElement>> Elements { get; set; } = new();
  184. public override bool Equals(object obj)
  185. {
  186. return obj is AvatarPart other && Equals(other);
  187. }
  188. public bool Equals(AvatarPart obj)
  189. {
  190. bool equal = true;
  191. equal &= Name == obj.Name;
  192. equal &= IconAssetId == obj.IconAssetId;
  193. equal &= Introduction == obj.Introduction;
  194. equal &= Palettes.Count == obj.Palettes.Count;
  195. if (equal == false) return false;
  196. for (int i = 0; i < Palettes.Count; ++i)
  197. {
  198. equal &= Palettes[i].Guid == obj.Palettes[i].Guid;
  199. equal &= Palettes[i].Name == obj.Palettes[i].Name;
  200. equal &= Palettes[i].Introduction == obj.Palettes[i].Introduction;
  201. equal &= Palettes[i].IconPaletteParams.Count == obj.Palettes[i].IconPaletteParams.Count;
  202. equal &= Palettes[i].ElementPaletteParams.Count == obj.Palettes[i].ElementPaletteParams.Count;
  203. if (equal == false) return false;
  204. for (int j = 0; j < Palettes[i].IconPaletteParams.Count; ++j)
  205. equal &= Palettes[i].IconPaletteParams[j].Equals(obj.Palettes[i].IconPaletteParams[j]);
  206. for (int j = 0; j < Palettes[i].ElementPaletteParams.Count; ++j)
  207. equal &= Palettes[i].ElementPaletteParams[j].Equals(obj.Palettes[i].ElementPaletteParams[j]);
  208. if (equal == false) return false;
  209. }
  210. equal &= Elements.Count == obj.Elements.Count;
  211. foreach (var pair in Elements)
  212. {
  213. equal &= obj.Elements.ContainsKey(pair.Key);
  214. equal &= pair.Value.Count == obj.Elements[pair.Key].Count;
  215. if (equal == false) return false;
  216. for (int i = 0; i < pair.Value.Count; ++i)
  217. equal &= obj.Elements[pair.Key][i].Equals(pair.Value[i]);
  218. if (equal == false) return false;
  219. }
  220. return equal;
  221. }
  222. public override int GetHashCode() { return (int)Guid; }
  223. }
  224. /// <summary>
  225. /// 一张Asset图片在pose中的偏移和层级等数据
  226. /// </summary>
  227. [Serializable]
  228. public struct AvatarElement
  229. {
  230. [JsonInclude] public int AssetId { get; set; }
  231. [JsonInclude] public int Layer { get; set; }
  232. [JsonInclude] public int LayerOffset { get; set; }
  233. [JsonInclude] public float PositionX { get; set; }
  234. [JsonInclude] public float PositionY { get; set; }
  235. [JsonInclude] public float Rotation { get; set; }
  236. [JsonInclude] public float ScaleX { get; set; }
  237. [JsonInclude] public float ScaleY { get; set; }
  238. [JsonInclude] public float Skew { get; set; }
  239. }
  240. [Serializable]
  241. public class AvatarBody() : AvatarPart { }
  242. [Serializable]
  243. public class AvatarHead(): AvatarPart { }
  244. [Serializable]
  245. public class AvatarHair(): AvatarPart { }
  246. [Serializable]
  247. public class AvatarFace() : AvatarPart { }
  248. [Serializable]
  249. public struct ClothClasses : IEquatable<ClothClasses>
  250. {
  251. [JsonInclude] public int Hash { get; set; }
  252. public EClothClasses_Type1 Type1()
  253. {
  254. return (EClothClasses_Type1)((Hash >> 16) & 0xFFFF);
  255. }
  256. public void SetType1(EClothClasses_Type1 value)
  257. {
  258. Hash = ((Hash & 0x0000FFFF) | (((short)value & 0xFFFF) << 16));
  259. }
  260. public short Type2()
  261. {
  262. return (short)(Hash & 0xFFFF);
  263. }
  264. public void SetType2(short value)
  265. {
  266. Hash = (int)((Hash & 0xFFFF0000u) | (uint)(value & 0xFFFF));
  267. }
  268. public ClothClasses(int hash)
  269. {
  270. Hash = hash;
  271. }
  272. public ClothClasses(EClothClasses_Type1 type1, short type2)
  273. {
  274. Hash = (((short)type1 & 0xFFFF) << 16) | (type2 & 0xFFFF);
  275. }
  276. public static implicit operator ClothClasses(int hash) => new ClothClasses(hash);
  277. public static implicit operator int(ClothClasses clothClasses) => clothClasses.Hash;
  278. public override bool Equals(object obj)
  279. {
  280. return obj is ClothClasses other && this.Hash == other.Hash;
  281. }
  282. public bool Equals(ClothClasses other)
  283. {
  284. return Hash == other.Hash;
  285. }
  286. public override int GetHashCode() => Hash;
  287. public static bool operator ==(ClothClasses left, ClothClasses right)
  288. {
  289. return left.Equals(right);
  290. }
  291. public static bool operator !=(ClothClasses left, ClothClasses right)
  292. {
  293. return !(left == right);
  294. }
  295. }
  296. /// <summary>
  297. /// 角色服装数据
  298. /// </summary>
  299. [Serializable]
  300. public class AvatarCloth() : AvatarPart
  301. {
  302. /// <summary>
  303. /// 服装分类
  304. /// </summary>
  305. [JsonInclude] public ClothClasses ClothClasses = new();
  306. /// <summary>
  307. /// 占用的身体槽。例如连衣裙会同时占用上身和下身的槽位,使得不能再穿其他上衣。
  308. /// key: BodySlot.Hash
  309. /// value: cost
  310. /// </summary>
  311. [JsonInclude] public Dictionary<int, int> BodySlotCost { get; set; } = new();
  312. public override bool Equals(object obj) { return obj is AvatarCloth other && Equals(other); }
  313. public bool Equals(AvatarCloth obj)
  314. {
  315. bool equal = base.Equals(obj);
  316. equal &= ClothClasses.Equals(obj.ClothClasses);
  317. equal &= BodySlotCost.Count == obj.BodySlotCost.Count;
  318. if (equal == false) return false;
  319. equal &= BodySlotCost.Count == obj.BodySlotCost.Count;
  320. foreach (var pair in BodySlotCost)
  321. {
  322. equal &= obj.BodySlotCost.ContainsKey(pair.Key);
  323. if (equal == false) return false;
  324. equal &= obj.BodySlotCost[pair.Key] == pair.Value;
  325. if (equal == false) return false;
  326. }
  327. return equal;
  328. }
  329. public override int GetHashCode() { return (int)Guid; }
  330. }
  331. [Serializable]
  332. public struct AvatarDollData()
  333. {
  334. [JsonInclude] public int FormatVersion { get; set; } = 0;
  335. [JsonInclude] public Metadata Metadata = new();
  336. [JsonInclude] public ProjectSettings Settings = new();
  337. /// <summary>
  338. /// Asset资源映射表
  339. /// 把AssetID对应到文件
  340. /// </summary>
  341. [JsonInclude] public Dictionary<int, string> AssetMap { get; set; } = new();
  342. [JsonInclude] public List<AvatarBody> Bodies { get; set; } = [];
  343. [JsonInclude] public List<AvatarHead> Heads { get; set; } = [];
  344. [JsonInclude] public List<AvatarHair> Hairs { get; set; } = [];
  345. [JsonInclude] public List<AvatarFace> Faces { get; set; } = [];
  346. [JsonInclude] public List<AvatarCloth> Clothes { get; set; } = [];
  347. public override bool Equals(object obj)
  348. {
  349. return obj is AvatarDollData other && Equals(other);
  350. }
  351. public bool Equals(AvatarDollData data)
  352. {
  353. bool equal = true;
  354. equal &= FormatVersion == data.FormatVersion;
  355. equal &= Metadata.Equals(data.Metadata);
  356. equal &= AssetMap.Count == data.AssetMap.Count;
  357. foreach (var pair in AssetMap)
  358. {
  359. equal &= data.AssetMap.ContainsKey(pair.Key);
  360. equal &= pair.Value == data.AssetMap[pair.Key];
  361. }
  362. equal &= Bodies.Count == data.Bodies.Count;
  363. for (int i = 0; i < data.Bodies.Count; ++i)
  364. equal &= Bodies[i].Equals(data.Bodies[i]);
  365. equal &= Faces.Count == data.Faces.Count;
  366. for (int i = 0; i < data.Faces.Count; ++i)
  367. equal &= Faces[i].Equals(data.Faces[i]);
  368. equal &= Hairs.Count == data.Hairs.Count;
  369. for (int i = 0; i < data.Hairs.Count; ++i)
  370. equal &= Hairs[i].Equals(data.Hairs[i]);
  371. equal &= Clothes.Count == data.Clothes.Count;
  372. for (int i = 0; i < data.Clothes.Count; ++i)
  373. equal &= Clothes[i].Equals(data.Clothes[i]);
  374. return equal;
  375. }
  376. }
  377. }