/unity/Assets/Futile/Extras/FRadialWipeSprite.cs

https://bitbucket.org/ironpencil/tankfight · C# · 338 lines · 267 code · 59 blank · 12 comment · 67 complexity · a9d50cb3b82b498417238c97fb3904f7 MD5 · raw file

  1. using UnityEngine;
  2. using System;
  3. public class FRadialWipeSprite : FSprite
  4. {
  5. protected float _baseAngle;
  6. protected float _percentage;
  7. protected bool _isClockwise;
  8. protected Vector2[] _meshVertices = new Vector2[7];
  9. protected Vector2[] _uvVertices = new Vector2[7];
  10. public FRadialWipeSprite (string elementName, bool isClockwise, float baseAngle, float percentage) : base()
  11. {
  12. _isClockwise = isClockwise;
  13. _baseAngle = (baseAngle + 36000000.0f) % 360.0f;
  14. _percentage = Mathf.Clamp01(percentage);
  15. Init(FFacetType.Triangle, Futile.atlasManager.GetElementWithName(elementName),5);
  16. _isAlphaDirty = true;
  17. UpdateLocalVertices();
  18. }
  19. private void CalculateTheRadialVertices ()
  20. {
  21. //TODO: A lot of these calculations could be offloaded to when the element (and maybe anchor?) changes.
  22. float baseAngleToUse;
  23. if(_isClockwise)
  24. {
  25. baseAngleToUse = _baseAngle;
  26. }
  27. else
  28. {
  29. baseAngleToUse = 360.0f-_baseAngle;
  30. }
  31. float startAngle = baseAngleToUse * RXMath.DTOR;
  32. float endAngle = startAngle + _percentage * RXMath.DOUBLE_PI;
  33. float halfWidth = _localRect.width*0.5f;
  34. float halfHeight = _localRect.height*0.5f;
  35. //corner 0 is the top right, the rest go clockwise from there
  36. Vector2 cornerTR = new Vector2(halfHeight, halfWidth);
  37. Vector2 cornerBR = new Vector2(-halfHeight, halfWidth);
  38. Vector2 cornerBL = new Vector2(-halfHeight, -halfWidth);
  39. Vector2 cornerTL = new Vector2(halfHeight, -halfWidth);
  40. float cornerAngleTR = -Mathf.Atan2(cornerTR.x,cornerTR.y) + RXMath.HALF_PI;
  41. float cornerAngleBR = -Mathf.Atan2(cornerBR.x,cornerBR.y) + RXMath.HALF_PI;
  42. float cornerAngleBL = -Mathf.Atan2(cornerBL.x,cornerBL.y) + RXMath.HALF_PI;
  43. float cornerAngleTL = -Mathf.Atan2(cornerTL.x,cornerTL.y) + RXMath.HALF_PI;
  44. cornerAngleTR = (cornerAngleTR + RXMath.DOUBLE_PI*10000.0f) % RXMath.DOUBLE_PI;
  45. cornerAngleBR = (cornerAngleBR + RXMath.DOUBLE_PI*10000.0f) % RXMath.DOUBLE_PI;
  46. cornerAngleBL = (cornerAngleBL + RXMath.DOUBLE_PI*10000.0f) % RXMath.DOUBLE_PI;
  47. cornerAngleTL = (cornerAngleTL + RXMath.DOUBLE_PI*10000.0f) % RXMath.DOUBLE_PI;
  48. float cornerAngle0;
  49. float cornerAngle1;
  50. float cornerAngle2;
  51. float cornerAngle3;
  52. if(startAngle < cornerAngleTR) //top right
  53. {
  54. cornerAngle0 = cornerAngleTR;
  55. cornerAngle1 = cornerAngleBR;
  56. cornerAngle2 = cornerAngleBL;
  57. cornerAngle3 = cornerAngleTL;
  58. }
  59. else if(startAngle >= cornerAngleTR && startAngle < cornerAngleBR) //right
  60. {
  61. cornerAngle0 = cornerAngleBR;
  62. cornerAngle1 = cornerAngleBL;
  63. cornerAngle2 = cornerAngleTL;
  64. cornerAngle3 = cornerAngleTR + RXMath.DOUBLE_PI;
  65. }
  66. else if(startAngle >= cornerAngleBR && startAngle < cornerAngleBL) //left
  67. {
  68. cornerAngle0 = cornerAngleBL;
  69. cornerAngle1 = cornerAngleTL;
  70. cornerAngle2 = cornerAngleTR + RXMath.DOUBLE_PI;
  71. cornerAngle3 = cornerAngleBR + RXMath.DOUBLE_PI;
  72. }
  73. else if(startAngle >= cornerAngleBL && startAngle < cornerAngleTL)
  74. {
  75. cornerAngle0 = cornerAngleTL;
  76. cornerAngle1 = cornerAngleTR + RXMath.DOUBLE_PI;
  77. cornerAngle2 = cornerAngleBR + RXMath.DOUBLE_PI;
  78. cornerAngle3 = cornerAngleBL + RXMath.DOUBLE_PI;
  79. }
  80. //else if(startAngle >= cornerAngleTL)
  81. else //top left
  82. {
  83. cornerAngle0 = cornerAngleTR + RXMath.DOUBLE_PI;
  84. cornerAngle1 = cornerAngleBR + RXMath.DOUBLE_PI;
  85. cornerAngle2 = cornerAngleBL + RXMath.DOUBLE_PI;
  86. cornerAngle3 = cornerAngleTL + RXMath.DOUBLE_PI;
  87. }
  88. float hugeRadius = 1000000.0f;
  89. for(int v = 0; v<6; v++)
  90. {
  91. float angle = 0;
  92. if(v<5)
  93. {
  94. angle = startAngle + ((endAngle - startAngle)/5.0f * v);
  95. if(v == 0)
  96. {
  97. //do nothing, 0 is gooood
  98. }
  99. else if(v == 1 && endAngle > cornerAngle0)
  100. {
  101. angle = cornerAngle0;
  102. }
  103. else if(v == 2 && endAngle > cornerAngle1)
  104. {
  105. angle = cornerAngle1;
  106. }
  107. else if(v == 3 && endAngle > cornerAngle2)
  108. {
  109. angle = cornerAngle2;
  110. }
  111. else if(v == 4 && endAngle > cornerAngle3)
  112. {
  113. angle = cornerAngle3;
  114. }
  115. else if(endAngle > cornerAngle3)
  116. {
  117. angle = Mathf.Max (angle, cornerAngle3);
  118. }
  119. else if(endAngle > cornerAngle2)
  120. {
  121. angle = Mathf.Max (angle, cornerAngle2);
  122. }
  123. else if(endAngle > cornerAngle1)
  124. {
  125. angle = Mathf.Max (angle, cornerAngle1);
  126. }
  127. else if(endAngle > cornerAngle0)
  128. {
  129. angle = Mathf.Max (angle, cornerAngle0);
  130. }
  131. }
  132. else
  133. {
  134. angle = endAngle;
  135. }
  136. angle = (angle + RXMath.DOUBLE_PI*10000.0f) % RXMath.DOUBLE_PI;
  137. float compX = Mathf.Cos(-angle + RXMath.HALF_PI) * hugeRadius;
  138. float compY = Mathf.Sin(-angle + RXMath.HALF_PI) * hugeRadius;
  139. //snap the verts to the edge of the rect
  140. if(angle < cornerAngleTR) //top right
  141. {
  142. compX = compX * (halfHeight / compY);
  143. compY = halfHeight;
  144. }
  145. else if(angle >= cornerAngleTR && angle < cornerAngleBR) //right
  146. {
  147. compY = compY * (halfWidth / compX);
  148. compX = halfWidth;
  149. }
  150. else if(angle >= cornerAngleBR && angle < cornerAngleBL) //bottom
  151. {
  152. compX = compX * (-halfHeight / compY);
  153. compY = -halfHeight;
  154. }
  155. else if(angle >= cornerAngleBL && angle < cornerAngleTL) //left
  156. {
  157. compY = compY * (-halfWidth / compX);
  158. compX = -halfWidth;
  159. }
  160. else if(angle >= cornerAngleTL) //top left
  161. {
  162. compX = compX * (halfHeight / compY);
  163. compY = halfHeight;
  164. }
  165. if(!_isClockwise)
  166. {
  167. compX = -compX;
  168. }
  169. _meshVertices[v] = new Vector2(compX, compY);
  170. }
  171. _meshVertices[6] = new Vector2(0,0); //this last vert is actually the center vert
  172. //create uv vertices
  173. Rect uvRect = _element.uvRect;
  174. Vector2 uvCenter = uvRect.center;
  175. for(int v = 0; v<7; v++)
  176. {
  177. _uvVertices[v].x = uvCenter.x + _meshVertices[v].x / _localRect.width * uvRect.width;
  178. _uvVertices[v].y = uvCenter.y + _meshVertices[v].y / _localRect.height * uvRect.height;
  179. }
  180. //put mesh vertices in the correct position
  181. float offsetX = _localRect.center.x;
  182. float offsetY = _localRect.center.y;
  183. for(int v = 0; v<7; v++)
  184. {
  185. _meshVertices[v].x += offsetX;
  186. _meshVertices[v].y += offsetY;
  187. }
  188. }
  189. override public void PopulateRenderLayer()
  190. {
  191. if(_isOnStage && _firstFacetIndex != -1)
  192. {
  193. _isMeshDirty = false;
  194. CalculateTheRadialVertices();
  195. //now do the actual population
  196. Vector3[] vertices = _renderLayer.vertices;
  197. Vector2[] uvs = _renderLayer.uvs;
  198. Color[] colors = _renderLayer.colors;
  199. int vertexIndex0 = _firstFacetIndex*3;
  200. //set the colors
  201. for(int c = 0; c<15; c++)
  202. {
  203. colors[vertexIndex0 + c] = _alphaColor;
  204. }
  205. //vertex 6 is the center vertex
  206. //set the uvs
  207. uvs[vertexIndex0] = _uvVertices[6];
  208. uvs[vertexIndex0 + 1] = _uvVertices[0];
  209. uvs[vertexIndex0 + 2] = _uvVertices[1];
  210. uvs[vertexIndex0 + 3] = _uvVertices[6];
  211. uvs[vertexIndex0 + 4] = _uvVertices[1];
  212. uvs[vertexIndex0 + 5] = _uvVertices[2];
  213. uvs[vertexIndex0 + 6] = _uvVertices[6];
  214. uvs[vertexIndex0 + 7] = _uvVertices[2];
  215. uvs[vertexIndex0 + 8] = _uvVertices[3];
  216. uvs[vertexIndex0 + 9] = _uvVertices[6];
  217. uvs[vertexIndex0 + 10] = _uvVertices[3];
  218. uvs[vertexIndex0 + 11] = _uvVertices[4];
  219. uvs[vertexIndex0 + 12] = _uvVertices[6];
  220. uvs[vertexIndex0 + 13] = _uvVertices[4];
  221. uvs[vertexIndex0 + 14] = _uvVertices[5];
  222. //set the mesh
  223. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0], _meshVertices[6],0);
  224. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 1], _meshVertices[0],0);
  225. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 2], _meshVertices[1],0);
  226. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 3], _meshVertices[6],0);
  227. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 4], _meshVertices[1],0);
  228. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 5], _meshVertices[2],0);
  229. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 6], _meshVertices[6],0);
  230. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 7], _meshVertices[2],0);
  231. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 8], _meshVertices[3],0);
  232. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 9], _meshVertices[6],0);
  233. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 10], _meshVertices[3],0);
  234. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 11], _meshVertices[4],0);
  235. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 12], _meshVertices[6],0);
  236. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 13], _meshVertices[4],0);
  237. _concatenatedMatrix.ApplyVector3FromLocalVector2(ref vertices[vertexIndex0 + 14], _meshVertices[5],0);
  238. _renderLayer.HandleVertsChange();
  239. }
  240. }
  241. public float baseAngle
  242. {
  243. get { return _baseAngle;}
  244. set
  245. {
  246. value = (value + 36000000.0f) % 360.0f;
  247. if(_baseAngle != value)
  248. {
  249. _baseAngle = value;
  250. _isMeshDirty = true;
  251. }
  252. }
  253. }
  254. public float percentage
  255. {
  256. get { return _percentage;}
  257. set
  258. {
  259. value = Mathf.Max (0.0f, Mathf.Min(1.0f, value));
  260. if(_percentage != value)
  261. {
  262. _percentage = value;
  263. _isMeshDirty = true;
  264. }
  265. }
  266. }
  267. public bool isClockwise
  268. {
  269. get { return _isClockwise;}
  270. set
  271. {
  272. if(_isClockwise != value)
  273. {
  274. _isClockwise = value;
  275. _isMeshDirty = true;
  276. }
  277. }
  278. }
  279. }