MeshData.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. namespace MagicaCloth
  7. {
  8. /// <summary>
  9. /// 仮想メッシュデータ
  10. /// データは必要な場合のみセットされる
  11. /// </summary>
  12. [System.Serializable]
  13. public class MeshData : ShareDataObject
  14. {
  15. /// <summary>
  16. /// データバージョン
  17. /// </summary>
  18. private const int DATA_VERSION = 2;
  19. /// <summary>
  20. /// 頂点ウエイト情報
  21. /// </summary>
  22. [System.Serializable]
  23. public struct VertexWeight
  24. {
  25. public Vector3 localPos;
  26. public Vector3 localNor;
  27. public Vector3 localTan;
  28. public int parentIndex;
  29. public float weight;
  30. }
  31. /// <summary>
  32. /// スキニングメッシュかどうか
  33. /// </summary>
  34. public bool isSkinning;
  35. /// <summary>
  36. /// 頂点数(必須)
  37. /// </summary>
  38. public int vertexCount;
  39. /// <summary>
  40. /// 頂点ごとのウエイト数とウエイト情報スタートインデックス
  41. /// 上位4bit = ウエイト数
  42. /// 下位28bit = スタートインデックス
  43. /// </summary>
  44. public uint[] vertexInfoList;
  45. /// <summary>
  46. /// 頂点ウエイトリスト
  47. /// </summary>
  48. public VertexWeight[] vertexWeightList;
  49. /// <summary>
  50. /// 頂点ハッシュデータ(オプション)
  51. /// </summary>
  52. public ulong[] vertexHashList;
  53. /// <summary>
  54. /// UVリスト(接線再計算用)
  55. /// </summary>
  56. public Vector2[] uvList;
  57. /// <summary>
  58. /// ライン数
  59. /// </summary>
  60. public int lineCount;
  61. /// <summary>
  62. /// ライン構成リスト(ライン数x2)
  63. /// </summary>
  64. public int[] lineList;
  65. /// <summary>
  66. /// トライアングル数
  67. /// </summary>
  68. public int triangleCount;
  69. /// <summary>
  70. /// トライアングル構成リスト(トライアングル数x3)
  71. /// </summary>
  72. public int[] triangleList;
  73. /// <summary>
  74. /// ボーン数
  75. /// </summary>
  76. public int boneCount;
  77. /// <summary>
  78. /// 仮想メッシュ頂点が属するトライアングル情報
  79. /// 上位8bit = 接続トライアングル数
  80. /// 下位24bit = 接続トライアングルリスト(vertexToTriangleIndexList)の開始インデックス
  81. /// </summary>
  82. public uint[] vertexToTriangleInfoList;
  83. /// <summary>
  84. /// 仮想メッシュ頂点が属するトライアングルインデックスリスト
  85. /// これは頂点数とは一致しない
  86. /// </summary>
  87. public int[] vertexToTriangleIndexList;
  88. /// <summary>
  89. /// 子メッシュの情報
  90. /// </summary>
  91. [System.Serializable]
  92. public class ChildData : IDataHash
  93. {
  94. /// <summary>
  95. /// 子メッシュデータのハッシュ
  96. /// </summary>
  97. public int childDataHash;
  98. /// <summary>
  99. /// 頂点数
  100. /// </summary>
  101. public int vertexCount;
  102. /// <summary>
  103. /// 頂点ごとのウエイト数とウエイト情報スタートインデックス
  104. /// 上位4bit = ウエイト数
  105. /// 下位28bit = スタートインデックス
  106. /// </summary>
  107. public uint[] vertexInfoList;
  108. /// <summary>
  109. /// 頂点ウエイトリスト
  110. /// </summary>
  111. public VertexWeight[] vertexWeightList;
  112. /// <summary>
  113. /// 元々属していた親仮想メッシュ頂点インデックス(エディット用)
  114. /// </summary>
  115. public int[] parentIndexList;
  116. public int VertexCount
  117. {
  118. get
  119. {
  120. return vertexCount;
  121. }
  122. }
  123. public int GetDataHash()
  124. {
  125. int hash = 0;
  126. hash += childDataHash;
  127. hash += vertexCount.GetDataHash();
  128. return hash;
  129. }
  130. }
  131. public List<ChildData> childDataList = new List<ChildData>();
  132. /// <summary>
  133. /// 設計時スケール
  134. /// </summary>
  135. public Vector3 baseScale;
  136. //=========================================================================================
  137. /// <summary>
  138. /// 頂点数
  139. /// </summary>
  140. public int VertexCount
  141. {
  142. get
  143. {
  144. return vertexCount;
  145. }
  146. }
  147. public int VertexHashCount
  148. {
  149. get
  150. {
  151. if (vertexHashList != null)
  152. return vertexHashList.Length;
  153. return 0;
  154. }
  155. }
  156. public int WeightCount
  157. {
  158. get
  159. {
  160. if (vertexWeightList != null)
  161. return vertexWeightList.Length;
  162. return 0;
  163. }
  164. }
  165. /// <summary>
  166. /// ライン数
  167. /// </summary>
  168. public int LineCount
  169. {
  170. get
  171. {
  172. return lineCount;
  173. }
  174. }
  175. /// <summary>
  176. /// トライアングル数
  177. /// </summary>
  178. public int TriangleCount
  179. {
  180. get
  181. {
  182. return triangleCount;
  183. }
  184. }
  185. /// <summary>
  186. /// ボーン数
  187. /// </summary>
  188. public int BoneCount
  189. {
  190. get
  191. {
  192. return boneCount;
  193. }
  194. }
  195. /// <summary>
  196. /// 子の数
  197. /// </summary>
  198. public int ChildCount
  199. {
  200. get
  201. {
  202. return childDataList.Count;
  203. }
  204. }
  205. //=========================================================================================
  206. /// <summary>
  207. /// データを識別するハッシュコードを作成して返す
  208. /// </summary>
  209. /// <returns></returns>
  210. public override int GetDataHash()
  211. {
  212. int hash = 0;
  213. hash += isSkinning.GetDataHash();
  214. hash += vertexCount.GetDataHash();
  215. hash += lineCount.GetDataHash();
  216. hash += triangleCount.GetDataHash();
  217. hash += boneCount.GetDataHash();
  218. hash += ChildCount.GetDataHash();
  219. hash += vertexInfoList.GetDataCountHash();
  220. hash += vertexWeightList.GetDataCountHash();
  221. hash += uvList.GetDataCountHash();
  222. hash += lineList.GetDataCountHash();
  223. hash += triangleList.GetDataCountHash();
  224. hash += childDataList.GetDataHash();
  225. // option
  226. if (vertexHashList != null && vertexHashList.Length > 0)
  227. hash += vertexHashList.GetDataCountHash();
  228. return hash;
  229. }
  230. //=========================================================================================
  231. public override int GetVersion()
  232. {
  233. return DATA_VERSION;
  234. }
  235. /// <summary>
  236. /// 現在のデータが正常(実行できる状態)か返す
  237. /// </summary>
  238. /// <returns></returns>
  239. public override Define.Error VerifyData()
  240. {
  241. if (dataHash == 0)
  242. return Define.Error.InvalidDataHash;
  243. //if (dataVersion != GetVersion())
  244. // return Define.Error.DataVersionMismatch;
  245. if (vertexCount == 0)
  246. return Define.Error.VertexCountZero;
  247. return Define.Error.None;
  248. }
  249. //=========================================================================================
  250. /// <summary>
  251. /// 仮想メッシュ頂点に対する最も影響が強い子頂点を辞書にして返す
  252. /// 仮想メッシュ頂点に影響する子頂点を辞書にして返す
  253. /// 子頂点はuintで上位16bitが子メッシュインデックス、下位16bitが子頂点インデックスとなる
  254. /// </summary>
  255. /// <returns></returns>
  256. public Dictionary<int, List<uint>> GetVirtualToChildVertexDict()
  257. {
  258. var dict = new Dictionary<int, List<uint>>();
  259. for (int i = 0; i < VertexCount; i++)
  260. dict.Add(i, new List<uint>());
  261. for (int i = 0; i < childDataList.Count; i++)
  262. {
  263. var cdata = childDataList[i];
  264. for (int j = 0; j < cdata.VertexCount; j++)
  265. {
  266. if (j < cdata.parentIndexList.Length)
  267. {
  268. int mvindex = cdata.parentIndexList[j];
  269. dict[mvindex].Add(DataUtility.Pack16(i, j));
  270. }
  271. }
  272. }
  273. return dict;
  274. }
  275. /// <summary>
  276. /// クロスメッシュ用に頂点セレクションデータを拡張する
  277. /// </summary>
  278. /// <param name="originalSelection"></param>
  279. /// <param name="extendNext">無効頂点の隣接が移動/固定頂点なら拡張に変更する</param>
  280. /// <param name="extendWeight">移動/固定頂点に影響する子頂点に接続する無効頂点は拡張に変更する</param>
  281. /// <returns></returns>
  282. public List<int> ExtendSelection(List<int> originalSelection, bool extendNext, bool extendWeight)
  283. {
  284. var selection = new List<int>(originalSelection);
  285. // (1)無効頂点の隣接が移動/固定頂点なら拡張に変更する
  286. if (extendNext)
  287. {
  288. // ライン/トライアングル情報を分解して各頂点ごとの接続頂点をリスト化
  289. List<HashSet<int>> vlink = MeshUtility.GetTriangleToVertexLinkList(vertexCount, new List<int>(lineList), new List<int>(triangleList));
  290. // 無効頂点の隣接が移動/固定頂点なら拡張に変更する
  291. List<int> changeIndexList = new List<int>();
  292. for (int i = 0; i < vertexCount; i++)
  293. {
  294. if (selection[i] == SelectionData.Invalid)
  295. {
  296. // 隣接を調べる
  297. var vset = vlink[i];
  298. foreach (var vindex in vset)
  299. {
  300. if (selection[vindex] == SelectionData.Move || selection[vindex] == SelectionData.Fixed)
  301. {
  302. // 拡張に変更する
  303. selection[i] = SelectionData.Extend;
  304. }
  305. }
  306. }
  307. }
  308. }
  309. // (2)移動/固定頂点に影響する子頂点に接続する無効頂点は拡張に変更する
  310. if (extendWeight)
  311. {
  312. var extendSet = new HashSet<int>();
  313. foreach (var cdata in childDataList)
  314. {
  315. for (int i = 0; i < cdata.VertexCount; i++)
  316. {
  317. // 頂点のウエイト数とウエイト開始インデックス
  318. uint pack = cdata.vertexInfoList[i];
  319. int wcnt = DataUtility.Unpack4_28Hi(pack);
  320. int wstart = DataUtility.Unpack4_28Low(pack);
  321. bool link = false;
  322. for (int j = 0; j < wcnt; j++)
  323. {
  324. int sindex = wstart + j;
  325. var vw = cdata.vertexWeightList[sindex];
  326. // この子頂点が移動/固定頂点に接続しているか判定する
  327. if (vw.weight > 0.0f && (selection[vw.parentIndex] == SelectionData.Move || selection[vw.parentIndex] == SelectionData.Fixed))
  328. link = true;
  329. }
  330. if (link)
  331. {
  332. for (int j = 0; j < wcnt; j++)
  333. {
  334. int sindex = wstart + j;
  335. var vw = cdata.vertexWeightList[sindex];
  336. // この子頂点が接続する頂点がInvalidの場合はExtendに変更する
  337. if (vw.weight > 0.0f && selection[vw.parentIndex] == SelectionData.Invalid)
  338. extendSet.Add(vw.parentIndex);
  339. }
  340. }
  341. }
  342. }
  343. foreach (var vindex in extendSet)
  344. {
  345. selection[vindex] = SelectionData.Extend;
  346. }
  347. }
  348. return selection;
  349. }
  350. }
  351. }