/src/away3d/primitives/Sphere.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 215 lines · 162 code · 24 blank · 29 comment · 20 complexity · cadbafa56b208002fc551e8204a9dd22 MD5 · raw file

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