CubismDrawable.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /**
  2. * Copyright(c) Live2D Inc. All rights reserved.
  3. *
  4. * Use of this source code is governed by the Live2D Open Software license
  5. * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
  6. */
  7. using Live2D.Cubism.Core.Unmanaged;
  8. using Live2D.Cubism.Framework;
  9. using UnityEngine;
  10. namespace Live2D.Cubism.Core
  11. {
  12. /// <summary>
  13. /// Single <see cref="CubismModel"/> drawable.
  14. /// </summary>
  15. [CubismDontMoveOnReimport]
  16. public sealed class CubismDrawable : MonoBehaviour
  17. {
  18. #region Factory Methods
  19. /// <summary>
  20. /// Creates drawables for a <see cref="CubismModel"/>.
  21. /// </summary>
  22. /// <param name="unmanagedModel">Handle to unmanaged model.</param>
  23. /// <returns>Drawables root.</returns>
  24. internal static GameObject CreateDrawables(CubismUnmanagedModel unmanagedModel)
  25. {
  26. var root = new GameObject("Drawables");
  27. // Create drawables.
  28. var unmanagedDrawables = unmanagedModel.Drawables;
  29. var buffer = new CubismDrawable[unmanagedDrawables.Count];
  30. for (var i = 0; i < buffer.Length; ++i)
  31. {
  32. var proxy = new GameObject();
  33. buffer[i] = proxy.AddComponent<CubismDrawable>();
  34. buffer[i].transform.SetParent(root.transform);
  35. buffer[i].Reset(unmanagedModel, i);
  36. }
  37. return root;
  38. }
  39. #endregion
  40. /// <summary>
  41. /// Unmanaged drawables from unmanaged model.
  42. /// </summary>
  43. private CubismUnmanagedDrawables UnmanagedDrawables { get; set; }
  44. /// <summary>
  45. /// <see cref="UnmanagedIndex"/> backing field.
  46. /// </summary>
  47. [SerializeField, HideInInspector]
  48. private int _unmanagedIndex = -1;
  49. /// <summary>
  50. /// Position in unmanaged arrays.
  51. /// </summary>
  52. internal int UnmanagedIndex
  53. {
  54. get { return _unmanagedIndex; }
  55. private set { _unmanagedIndex = value; }
  56. }
  57. /// <summary>
  58. /// Copy of Id.
  59. /// </summary>
  60. public string Id
  61. {
  62. get
  63. {
  64. // Pull data.
  65. return UnmanagedDrawables.Ids[UnmanagedIndex];
  66. }
  67. }
  68. /// <summary>
  69. /// Texture UnmanagedIndex.
  70. /// </summary>
  71. public int TextureIndex
  72. {
  73. get
  74. {
  75. // Pull data.
  76. return UnmanagedDrawables.TextureIndices[UnmanagedIndex];
  77. }
  78. }
  79. /// <summary>
  80. /// Copy of the masks.
  81. /// </summary>
  82. public CubismDrawable[] Masks
  83. {
  84. get
  85. {
  86. var drawables = this
  87. .FindCubismModel(true)
  88. .Drawables;
  89. // Get addresses.
  90. var counts = UnmanagedDrawables.MaskCounts;
  91. var indices = UnmanagedDrawables.Masks;
  92. // Pull data.
  93. var buffer = new CubismDrawable[counts[UnmanagedIndex]];
  94. for (var i = 0; i < buffer.Length; ++i)
  95. {
  96. for (var j = 0; j < drawables.Length; ++j)
  97. {
  98. if (drawables[j].UnmanagedIndex != indices[UnmanagedIndex][i])
  99. {
  100. continue;
  101. }
  102. buffer[i] = drawables[j];
  103. break;
  104. }
  105. }
  106. return buffer;
  107. }
  108. }
  109. /// <summary>
  110. /// Copy of vertex positions.
  111. /// </summary>
  112. public Vector3[] VertexPositions
  113. {
  114. get
  115. {
  116. // Get addresses.
  117. var counts = UnmanagedDrawables.VertexCounts;
  118. var positions = UnmanagedDrawables.VertexPositions;
  119. // Pull data.
  120. var buffer = new Vector3[counts[UnmanagedIndex]];
  121. for (var i = 0; i < buffer.Length; ++i)
  122. {
  123. buffer[i] = new Vector3(
  124. positions[UnmanagedIndex][(i * 2) + 0],
  125. positions[UnmanagedIndex][(i * 2) + 1]
  126. );
  127. }
  128. return buffer;
  129. }
  130. }
  131. /// <summary>
  132. /// Copy of vertex texture coordinates.
  133. /// </summary>
  134. public Vector2[] VertexUvs
  135. {
  136. get
  137. {
  138. // Get addresses.
  139. var counts = UnmanagedDrawables.VertexCounts;
  140. var uvs = UnmanagedDrawables.VertexUvs;
  141. // Pull data.
  142. var buffer = new Vector2[counts[UnmanagedIndex]];
  143. for (var i = 0; i < buffer.Length; ++i)
  144. {
  145. buffer[i] = new Vector2(
  146. uvs[UnmanagedIndex][(i * 2) + 0],
  147. uvs[UnmanagedIndex][(i * 2) + 1]
  148. );
  149. }
  150. return buffer;
  151. }
  152. }
  153. /// <summary>
  154. /// Copy of triangle indices.
  155. /// </summary>
  156. public int[] Indices
  157. {
  158. get
  159. {
  160. // Get addresses.
  161. var counts = UnmanagedDrawables.IndexCounts;
  162. var indices = UnmanagedDrawables.Indices;
  163. // Pull data.
  164. var buffer = new int[counts[UnmanagedIndex]];
  165. for (var i = 0; i < buffer.Length; ++i)
  166. {
  167. buffer[i] = indices[UnmanagedIndex][i];
  168. }
  169. return buffer;
  170. }
  171. }
  172. /// <summary>
  173. /// True if double-sided.
  174. /// </summary>
  175. public bool IsDoubleSided
  176. {
  177. get
  178. {
  179. // Get address.
  180. var flags = UnmanagedDrawables.ConstantFlags;
  181. // Pull data.
  182. return flags[UnmanagedIndex].HasIsDoubleSidedFlag();
  183. }
  184. }
  185. /// <summary>
  186. /// True if masking is requested.
  187. /// </summary>
  188. public bool IsMasked
  189. {
  190. get
  191. {
  192. // Get address.
  193. var counts = UnmanagedDrawables.MaskCounts;
  194. // Pull data.
  195. return counts[UnmanagedIndex] > 0;
  196. }
  197. }
  198. /// <summary>
  199. /// True if inverted mask.
  200. /// </summary>
  201. public bool IsInverted
  202. {
  203. get
  204. {
  205. // Get address.
  206. var flags = UnmanagedDrawables.ConstantFlags;
  207. // Pull data.
  208. return flags[UnmanagedIndex].HasIsInvertedMaskFlag();
  209. }
  210. }
  211. /// <summary>
  212. /// True if additive blending is requested.
  213. /// </summary>
  214. public bool BlendAdditive
  215. {
  216. get
  217. {
  218. // Get address.
  219. var flags = UnmanagedDrawables.ConstantFlags;
  220. // Pull data.
  221. return flags[UnmanagedIndex].HasBlendAdditiveFlag();
  222. }
  223. }
  224. /// <summary>
  225. /// True if multiply blending is setd.
  226. /// </summary>
  227. public bool MultiplyBlend
  228. {
  229. get
  230. {
  231. // Get address.
  232. var flags = UnmanagedDrawables.ConstantFlags;
  233. // Pull data.
  234. return flags[UnmanagedIndex].HasBlendMultiplicativeFlag();
  235. }
  236. }
  237. /// <summary>
  238. /// Revives instance.
  239. /// </summary>
  240. /// <param name="unmanagedModel">Handle to unmanaged model.</param>
  241. internal void Revive(CubismUnmanagedModel unmanagedModel)
  242. {
  243. UnmanagedDrawables = unmanagedModel.Drawables;
  244. }
  245. /// <summary>
  246. /// Restores instance to initial state.
  247. /// </summary>
  248. /// <param name="unmanagedModel">Handle to unmanaged model.</param>
  249. /// <param name="unmanagedIndex">Position in unmanaged arrays.</param>
  250. private void Reset(CubismUnmanagedModel unmanagedModel, int unmanagedIndex)
  251. {
  252. Revive(unmanagedModel);
  253. UnmanagedIndex = unmanagedIndex;
  254. name = Id;
  255. }
  256. }
  257. }