/src/away3d/primitives/Capsule.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 243 lines · 184 code · 26 blank · 33 comment · 17 complexity · b1a4b782c1cda4a3126f16a6df7bacfc MD5 · raw file

  1. package away3d.primitives
  2. {
  3. import away3d.core.base.SubGeometry;
  4. import away3d.materials.MaterialBase;
  5. /**
  6. * A UV Capsule primitive mesh.
  7. */
  8. public class Capsule extends PrimitiveBase
  9. {
  10. private var _radius:Number;
  11. private var _height:Number;
  12. private var _segmentsW:uint;
  13. private var _segmentsH:uint;
  14. private var _yUp:Boolean;
  15. /**
  16. * Creates a new Capsule object.
  17. * @param material The material with which to render the capsule.
  18. * @param radius The radius of the capsule.
  19. * @param height The height of the capsule.
  20. * @param segmentsW Defines the number of horizontal segments that make up the capsule. Defaults to 16.
  21. * @param segmentsH Defines the number of vertical segments that make up the capsule. Defaults to 12.
  22. * @param yUp Defines whether the capsule poles should lay on the Y-axis (true) or on the Z-axis (false).
  23. */
  24. public function Capsule(material:MaterialBase, radius:Number = 50, height:Number = 100, segmentsW:uint = 16, segmentsH:uint = 12, yUp:Boolean = true)
  25. {
  26. super(material);
  27. _radius = radius;
  28. _height = height;
  29. _segmentsW = segmentsW;
  30. _segmentsH = segmentsH;
  31. _yUp = yUp;
  32. }
  33. /**
  34. * @inheritDoc
  35. */
  36. protected override function buildGeometry(target:SubGeometry):void
  37. {
  38. var vertices:Vector.<Number>;
  39. var vertexNormals:Vector.<Number>;
  40. var vertexTangents:Vector.<Number>;
  41. var indices:Vector.<uint>;
  42. var i:uint, j:uint, triIndex:uint;
  43. var numVerts:uint = (_segmentsH + 1)*(_segmentsW + 1);
  44. if(numVerts == target.numVertices)
  45. {
  46. vertices = target.vertexData;
  47. vertexNormals = target.vertexNormalData;
  48. vertexTangents = target.vertexTangentData;
  49. indices = target.indexData;
  50. }
  51. else
  52. {
  53. vertices = new Vector.<Number>(numVerts*3, true);
  54. vertexNormals = new Vector.<Number>(numVerts*3, true);
  55. vertexTangents = new Vector.<Number>(numVerts*3, true);
  56. indices = new Vector.<uint>((_segmentsH - 1)*_segmentsW*6, true);
  57. }
  58. numVerts = 0;
  59. for(j = 0; j <= _segmentsH; ++j)
  60. {
  61. var horangle:Number = Math.PI*j/_segmentsH;
  62. var z:Number = -_radius*Math.cos(horangle);
  63. var ringradius:Number = _radius*Math.sin(horangle);
  64. for(i = 0; i <= _segmentsW; ++i)
  65. {
  66. var verangle:Number = 2*Math.PI*i/_segmentsW;
  67. var x:Number = ringradius*Math.cos(verangle);
  68. var offset:Number = j > _segmentsH/2 ? _height/2 : -_height/2;
  69. var y:Number = ringradius*Math.sin(verangle);
  70. var normLen:Number = 1/Math.sqrt(x*x + y*y + z*z);
  71. var tanLen:Number = Math.sqrt(y*y + x*x);
  72. if(_yUp)
  73. {
  74. vertexNormals[numVerts] = x*normLen;
  75. vertexTangents[numVerts] = tanLen > .007 ? -y/tanLen : 1;
  76. vertices[numVerts++] = x;
  77. vertexNormals[numVerts] = -z*normLen;
  78. vertexTangents[numVerts] = 0;
  79. vertices[numVerts++] = -z - offset;
  80. vertexNormals[numVerts] = y*normLen;
  81. vertexTangents[numVerts] = tanLen > .007 ? x/tanLen : 0;
  82. vertices[numVerts++] = y;
  83. }
  84. else
  85. {
  86. vertexNormals[numVerts] = x*normLen;
  87. vertexTangents[numVerts] = tanLen > .007 ? -y/tanLen : 1;
  88. vertices[numVerts++] = x;
  89. vertexNormals[numVerts] = y*normLen;
  90. vertexTangents[numVerts] = tanLen > .007 ? x/tanLen : 0;
  91. vertices[numVerts++] = y;
  92. vertexNormals[numVerts] = z*normLen;
  93. vertexTangents[numVerts] = 0;
  94. vertices[numVerts++] = z + offset;
  95. }
  96. if(i > 0 && j > 0)
  97. {
  98. var a:int = (_segmentsW + 1)*j + i;
  99. var b:int = (_segmentsW + 1)*j + i - 1;
  100. var c:int = (_segmentsW + 1)*(j - 1) + i - 1;
  101. var d:int = (_segmentsW + 1)*(j - 1) + i;
  102. if(j == _segmentsH)
  103. {
  104. indices[triIndex++] = a;
  105. indices[triIndex++] = c;
  106. indices[triIndex++] = d;
  107. }
  108. else if(j == 1)
  109. {
  110. indices[triIndex++] = a;
  111. indices[triIndex++] = b;
  112. indices[triIndex++] = c;
  113. }
  114. else
  115. {
  116. indices[triIndex++] = a;
  117. indices[triIndex++] = b;
  118. indices[triIndex++] = c;
  119. indices[triIndex++] = a;
  120. indices[triIndex++] = c;
  121. indices[triIndex++] = d;
  122. }
  123. }
  124. }
  125. }
  126. target.updateVertexData(vertices);
  127. target.updateVertexNormalData(vertexNormals);
  128. target.updateVertexTangentData(vertexTangents);
  129. target.updateIndexData(indices);
  130. }
  131. /**
  132. * @inheritDoc
  133. */
  134. protected override function buildUVs(target:SubGeometry):void
  135. {
  136. var i:int, j:int;
  137. var numUvs:uint = (_segmentsH + 1)*(_segmentsW + 1)*2;
  138. var uvData:Vector.<Number>;
  139. if(target.UVData && numUvs == target.UVData.length)
  140. uvData = target.UVData;
  141. else
  142. uvData = new Vector.<Number>(numUvs, true);
  143. numUvs = 0;
  144. for(j = 0; j <= _segmentsH; ++j)
  145. {
  146. for(i = 0; i <= _segmentsW; ++i)
  147. {
  148. uvData[numUvs++] = i/_segmentsW;
  149. uvData[numUvs++] = j/_segmentsH;
  150. }
  151. }
  152. target.updateUVData(uvData);
  153. }
  154. /**
  155. * The radius of the capsule.
  156. */
  157. public function get radius():Number
  158. {
  159. return _radius;
  160. }
  161. public function set radius(value:Number):void
  162. {
  163. _radius = value;
  164. invalidateGeometry();
  165. }
  166. /**
  167. * The height of the capsule.
  168. */
  169. public function get height():Number
  170. {
  171. return _height;
  172. }
  173. public function set height(value:Number):void
  174. {
  175. _height = value;
  176. invalidateGeometry();
  177. }
  178. /**
  179. * Defines the number of horizontal segments that make up the capsule. Defaults to 16.
  180. */
  181. public function get segmentsW():uint
  182. {
  183. return _segmentsW;
  184. }
  185. public function set segmentsW(value:uint):void
  186. {
  187. _segmentsW = value;
  188. invalidateGeometry();
  189. invalidateUVs();
  190. }
  191. /**
  192. * Defines the number of vertical segments that make up the capsule. Defaults to 12.
  193. */
  194. public function get segmentsH():uint
  195. {
  196. return _segmentsH;
  197. }
  198. public function set segmentsH(value:uint):void
  199. {
  200. _segmentsH = value;
  201. invalidateGeometry();
  202. invalidateUVs();
  203. }
  204. /**
  205. * Defines whether the capsule poles should lay on the Y-axis (true) or on the Z-axis (false).
  206. */
  207. public function get yUp():Boolean
  208. {
  209. return _yUp;
  210. }
  211. public function set yUp(value:Boolean):void
  212. {
  213. _yUp = value;
  214. invalidateGeometry();
  215. }
  216. }
  217. }