TransformDB.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2012-2017 DragonBones team and other contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. using System;
  24. namespace DragonBones
  25. {
  26. /// <summary>
  27. /// - 2D Transform.
  28. /// </summary>
  29. /// <version>DragonBones 3.0</version>
  30. /// <language>en_US</language>
  31. /// <summary>
  32. /// - 2D 变换。
  33. /// </summary>
  34. /// <version>DragonBones 3.0</version>
  35. /// <language>zh_CN</language>
  36. public class TransformDB
  37. {
  38. /// <private/>
  39. public static readonly float PI = 3.141593f;
  40. /// <private/>
  41. public static readonly float PI_D = PI * 2.0f;
  42. /// <private/>
  43. public static readonly float PI_H = PI / 2.0f;
  44. /// <private/>
  45. public static readonly float PI_Q = PI / 4.0f;
  46. /// <private/>
  47. public static readonly float RAD_DEG = 180.0f / PI;
  48. /// <private/>
  49. public static readonly float DEG_RAD = PI / 180.0f;
  50. /// <private/>
  51. public static float NormalizeRadian(float value)
  52. {
  53. value = (value + PI) % (PI * 2.0f);
  54. value += value > 0.0f ? -PI : PI;
  55. return value;
  56. }
  57. /// <summary>
  58. /// - Horizontal translate.
  59. /// </summary>
  60. /// <version>DragonBones 3.0</version>
  61. /// <language>en_US</language>
  62. /// <summary>
  63. /// - 水平位移。
  64. /// </summary>
  65. /// <version>DragonBones 3.0</version>
  66. /// <language>zh_CN</language>
  67. public float x = 0.0f;
  68. /// <summary>
  69. /// - Vertical translate.
  70. /// </summary>
  71. /// <version>DragonBones 3.0</version>
  72. /// <language>en_US</language>
  73. /// <summary>
  74. /// - 垂直位移。
  75. /// </summary>
  76. /// <version>DragonBones 3.0</version>
  77. /// <language>zh_CN</language>
  78. public float y = 0.0f;
  79. /// <summary>
  80. /// - Skew. (In radians)
  81. /// </summary>
  82. /// <version>DragonBones 3.0</version>
  83. /// <language>en_US</language>
  84. /// <summary>
  85. /// - 倾斜。 (以弧度为单位)
  86. /// </summary>
  87. /// <version>DragonBones 3.0</version>
  88. /// <language>zh_CN</language>
  89. public float skew = 0.0f;
  90. /// <summary>
  91. /// - rotation. (In radians)
  92. /// </summary>
  93. /// <version>DragonBones 3.0</version>
  94. /// <language>en_US</language>
  95. /// <summary>
  96. /// - 旋转。 (以弧度为单位)
  97. /// </summary>
  98. /// <version>DragonBones 3.0</version>
  99. /// <language>zh_CN</language>
  100. public float rotation = 0.0f;
  101. /// <summary>
  102. /// - Horizontal Scaling.
  103. /// </summary>
  104. /// <version>DragonBones 3.0</version>
  105. /// <language>en_US</language>
  106. /// <summary>
  107. /// - 水平缩放。
  108. /// </summary>
  109. /// <version>DragonBones 3.0</version>
  110. /// <language>zh_CN</language>
  111. public float scaleX = 1.0f;
  112. /// <summary>
  113. /// - Vertical scaling.
  114. /// </summary>
  115. /// <version>DragonBones 3.0</version>
  116. /// <language>en_US</language>
  117. /// <summary>
  118. /// - 垂直缩放。
  119. /// </summary>
  120. /// <version>DragonBones 3.0</version>
  121. /// <language>zh_CN</language>
  122. public float scaleY = 1.0f;
  123. /// <private/>
  124. public TransformDB()
  125. {
  126. }
  127. public override string ToString()
  128. {
  129. return "[object dragonBones.Transform] x:" + this.x + " y:" + this.y + " skew:" + this.skew* 180.0 / PI + " rotation:" + this.rotation* 180.0 / PI + " scaleX:" + this.scaleX + " scaleY:" + this.scaleY;
  130. }
  131. /// <private/>
  132. public TransformDB CopyFrom(TransformDB value)
  133. {
  134. this.x = value.x;
  135. this.y = value.y;
  136. this.skew = value.skew;
  137. this.rotation = value.rotation;
  138. this.scaleX = value.scaleX;
  139. this.scaleY = value.scaleY;
  140. return this;
  141. }
  142. /// <private/>
  143. public TransformDB Identity()
  144. {
  145. this.x = this.y = 0.0f;
  146. this.skew = this.rotation = 0.0f;
  147. this.scaleX = this.scaleY = 1.0f;
  148. return this;
  149. }
  150. /// <private/>
  151. public TransformDB Add(TransformDB value)
  152. {
  153. this.x += value.x;
  154. this.y += value.y;
  155. this.skew += value.skew;
  156. this.rotation += value.rotation;
  157. this.scaleX *= value.scaleX;
  158. this.scaleY *= value.scaleY;
  159. return this;
  160. }
  161. /// <private/>
  162. public TransformDB Minus(TransformDB value)
  163. {
  164. this.x -= value.x;
  165. this.y -= value.y;
  166. this.skew -= value.skew;
  167. this.rotation -= value.rotation;
  168. this.scaleX /= value.scaleX;
  169. this.scaleY /= value.scaleY;
  170. return this;
  171. }
  172. /// <private/>
  173. public TransformDB FromMatrix(Matrix matrix)
  174. {
  175. var backupScaleX = this.scaleX;
  176. var backupScaleY = this.scaleY;
  177. this.x = matrix.tx;
  178. this.y = matrix.ty;
  179. var skewX = (float)Math.Atan(-matrix.c / matrix.d);
  180. this.rotation = (float)Math.Atan(matrix.b / matrix.a);
  181. if(float.IsNaN(skewX))
  182. {
  183. skewX = 0.0f;
  184. }
  185. if(float.IsNaN(this.rotation))
  186. {
  187. this.rotation = 0.0f;
  188. }
  189. this.scaleX = (float)((this.rotation > -PI_Q && this.rotation < PI_Q) ? matrix.a / Math.Cos(this.rotation) : matrix.b / Math.Sin(this.rotation));
  190. this.scaleY = (float)((skewX > -PI_Q && skewX < PI_Q) ? matrix.d / Math.Cos(skewX) : -matrix.c / Math.Sin(skewX));
  191. if (backupScaleX >= 0.0f && this.scaleX < 0.0f)
  192. {
  193. this.scaleX = -this.scaleX;
  194. this.rotation = this.rotation - PI;
  195. }
  196. if (backupScaleY >= 0.0f && this.scaleY < 0.0f)
  197. {
  198. this.scaleY = -this.scaleY;
  199. skewX = skewX - PI;
  200. }
  201. this.skew = skewX - this.rotation;
  202. return this;
  203. }
  204. /// <private/>
  205. public TransformDB ToMatrix(Matrix matrix)
  206. {
  207. if(this.rotation == 0.0f)
  208. {
  209. matrix.a = 1.0f;
  210. matrix.b = 0.0f;
  211. }
  212. else
  213. {
  214. matrix.a = (float)Math.Cos(this.rotation);
  215. matrix.b = (float)Math.Sin(this.rotation);
  216. }
  217. if(this.skew == 0.0f)
  218. {
  219. matrix.c = -matrix.b;
  220. matrix.d = matrix.a;
  221. }
  222. else
  223. {
  224. matrix.c = -(float)Math.Sin(this.skew + this.rotation);
  225. matrix.d = (float)Math.Cos(this.skew + this.rotation);
  226. }
  227. if(this.scaleX != 1.0f)
  228. {
  229. matrix.a *= this.scaleX;
  230. matrix.b *= this.scaleX;
  231. }
  232. if(this.scaleY != 1.0f)
  233. {
  234. matrix.c *= this.scaleY;
  235. matrix.d *= this.scaleY;
  236. }
  237. matrix.tx = this.x;
  238. matrix.ty = this.y;
  239. return this;
  240. }
  241. }
  242. }