ArrayExtensionMethods.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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 System;
  9. using UnityEngine;
  10. namespace Live2D.Cubism.Core
  11. {
  12. /// <summary>
  13. /// Extension for Cubism related arrays.
  14. /// </summary>
  15. public static class ArrayExtensionMethods
  16. {
  17. #region Parameters
  18. /// <summary>
  19. /// Finds a <see cref="CubismParameter"/> by its ID.
  20. /// </summary>
  21. /// <param name="self">Container.</param>
  22. /// <param name="id">ID to match.</param>
  23. /// <returns>Parameter on success; <see langword="null"/> otherwise.</returns>
  24. public static CubismParameter FindById(this CubismParameter[] self, string id)
  25. {
  26. if (self == null)
  27. {
  28. return null;
  29. }
  30. for (var i = 0; i < self.Length; ++i)
  31. {
  32. if (self[i].name != id)
  33. {
  34. continue;
  35. }
  36. return self[i];
  37. }
  38. return null;
  39. }
  40. /// <summary>
  41. /// Revives (and sorts) <see cref="CubismParameter"/>s.
  42. /// </summary>
  43. /// <param name="self">Container.</param>
  44. /// <param name="model">TaskableModel to unmanaged model.</param>
  45. internal static void Revive(this CubismParameter[] self, CubismUnmanagedModel model)
  46. {
  47. Array.Sort(self, (a, b) => a.UnmanagedIndex - b.UnmanagedIndex);
  48. for (var i = 0; i < self.Length; ++i)
  49. {
  50. self[i].Revive(model);
  51. }
  52. }
  53. /// <summary>
  54. /// Writes opacities to unmanaged model.
  55. /// </summary>
  56. /// <param name="self">Source buffer.</param>
  57. /// <param name="unmanagedModel"></param>
  58. internal static void WriteTo(this CubismParameter[] self, CubismUnmanagedModel unmanagedModel)
  59. {
  60. // Get address.
  61. var unmanagedParameters = unmanagedModel.Parameters;
  62. var values = unmanagedParameters.Values;
  63. // Push.
  64. for (var i = 0; i < self.Length; ++i)
  65. {
  66. values[self[i].UnmanagedIndex] = self[i].Value;
  67. }
  68. }
  69. /// <summary>
  70. /// Writes opacities to unmanaged model.
  71. /// </summary>
  72. /// <param name="self">Source buffer.</param>
  73. /// <param name="unmanagedModel"></param>
  74. internal static void ReadFrom(this CubismParameter[] self, CubismUnmanagedModel unmanagedModel)
  75. {
  76. // Get address.
  77. var unmanagedParameters = unmanagedModel.Parameters;
  78. var values = unmanagedParameters.Values;
  79. // Pull.
  80. for (var i = 0; i < self.Length; ++i)
  81. {
  82. self[i].Value = values[self[i].UnmanagedIndex];
  83. }
  84. }
  85. #endregion
  86. #region Parts
  87. /// <summary>
  88. /// Finds a <see cref="CubismPart"/> by its ID.
  89. /// </summary>
  90. /// <param name="self"><see langword="this"/>.</param>
  91. /// <param name="id">ID to match.</param>
  92. /// <returns>Part if found; <see langword="null"/> otherwise.</returns>
  93. public static CubismPart FindById(this CubismPart[] self, string id)
  94. {
  95. if (self == null)
  96. {
  97. return null;
  98. }
  99. for (var i = 0; i < self.Length; ++i)
  100. {
  101. if (self[i].name != id)
  102. {
  103. continue;
  104. }
  105. return self[i];
  106. }
  107. return null;
  108. }
  109. /// <summary>
  110. /// Revives (and sorts) <see cref="CubismPart"/>s.
  111. /// </summary>
  112. /// <param name="self">Container.</param>
  113. /// <param name="model">TaskableModel to unmanaged model.</param>
  114. internal static void Revive(this CubismPart[] self, CubismUnmanagedModel model)
  115. {
  116. Array.Sort(self, (a, b) => a.UnmanagedIndex - b.UnmanagedIndex);
  117. for (var i = 0; i < self.Length; ++i)
  118. {
  119. self[i].Revive(model);
  120. }
  121. }
  122. /// <summary>
  123. /// Writes opacities to unmanaged model.
  124. /// </summary>
  125. /// <param name="self">Source buffer.</param>
  126. /// <param name="unmanagedModel"></param>
  127. internal static void WriteTo(this CubismPart[] self, CubismUnmanagedModel unmanagedModel)
  128. {
  129. // Get address.
  130. var unmanagedParts = unmanagedModel.Parts;
  131. var opacities = unmanagedParts.Opacities;
  132. // Push.
  133. for (var i = 0; i < self.Length; ++i)
  134. {
  135. opacities[self[i].UnmanagedIndex] = self[i].Opacity;
  136. }
  137. }
  138. #endregion
  139. #region Drawables
  140. /// <summary>
  141. /// Finds a <see cref="CubismParameter"/> by its ID.
  142. /// </summary>
  143. /// <param name="self"><see langword="this"/>.</param>
  144. /// <param name="id">ID to match.</param>
  145. /// <returns>Part if found; <see langword="null"/> otherwise.</returns>
  146. public static CubismDrawable FindById(this CubismDrawable[] self, string id)
  147. {
  148. if (self == null)
  149. {
  150. return null;
  151. }
  152. for (var i = 0; i < self.Length; ++i)
  153. {
  154. if (self[i].name != id)
  155. {
  156. continue;
  157. }
  158. return self[i];
  159. }
  160. return null;
  161. }
  162. /// <summary>
  163. /// Revives (and sorts) <see cref="CubismDrawable"/>s.
  164. /// </summary>
  165. /// <param name="self">Container.</param>
  166. /// <param name="model">TaskableModel to unmanaged model.</param>
  167. internal static void Revive(this CubismDrawable[] self, CubismUnmanagedModel model)
  168. {
  169. Array.Sort(self, (a, b) => a.UnmanagedIndex - b.UnmanagedIndex);
  170. for (var i = 0; i < self.Length; ++i)
  171. {
  172. self[i].Revive(model);
  173. }
  174. }
  175. /// <summary>
  176. /// Reads new data from a model.
  177. /// </summary>
  178. /// <param name="self">Buffer to write to.</param>
  179. /// <param name="unmanagedModel">Unmanaged model to read from.</param>
  180. internal static unsafe void ReadFrom(this CubismDynamicDrawableData[] self, CubismUnmanagedModel unmanagedModel)
  181. {
  182. // Get addresses.
  183. var drawables = unmanagedModel.Drawables;
  184. var flags = drawables.DynamicFlags;
  185. var opacities = drawables.Opacities;
  186. var drawOrders = drawables.DrawOrders;
  187. var renderOrders = drawables.RenderOrders;
  188. var vertexPositions = drawables.VertexPositions;
  189. // Pull data.
  190. for (var i = 0; i < self.Length; ++i)
  191. {
  192. var data = self[i];
  193. data.Flags = flags[i];
  194. data.Opacity = opacities[i];
  195. data.DrawOrder = drawOrders[i];
  196. data.RenderOrder = renderOrders[i];
  197. // Read vertex positions only if necessary.
  198. if (!data.AreVertexPositionsDirty)
  199. {
  200. continue;
  201. }
  202. // Copy vertex positions.
  203. fixed (Vector3* dataVertexPositions = data.VertexPositions)
  204. {
  205. for (var v = 0; v < data.VertexPositions.Length; ++v)
  206. {
  207. dataVertexPositions[v].x = vertexPositions[i][(v * 2) + 0];
  208. dataVertexPositions[v].y = vertexPositions[i][(v * 2) + 1];
  209. }
  210. }
  211. }
  212. // Clear dynamic flags.
  213. drawables.ResetDynamicFlags();
  214. }
  215. #endregion
  216. }
  217. }