CylinderOutlineGeometry.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import arrayFill from './arrayFill.js';
  2. import BoundingSphere from './BoundingSphere.js';
  3. import Cartesian2 from './Cartesian2.js';
  4. import Cartesian3 from './Cartesian3.js';
  5. import Check from './Check.js';
  6. import ComponentDatatype from './ComponentDatatype.js';
  7. import CylinderGeometryLibrary from './CylinderGeometryLibrary.js';
  8. import defaultValue from './defaultValue.js';
  9. import defined from './defined.js';
  10. import DeveloperError from './DeveloperError.js';
  11. import Geometry from './Geometry.js';
  12. import GeometryAttribute from './GeometryAttribute.js';
  13. import GeometryAttributes from './GeometryAttributes.js';
  14. import GeometryOffsetAttribute from './GeometryOffsetAttribute.js';
  15. import IndexDatatype from './IndexDatatype.js';
  16. import PrimitiveType from './PrimitiveType.js';
  17. var radiusScratch = new Cartesian2();
  18. /**
  19. * A description of the outline of a cylinder.
  20. *
  21. * @alias CylinderOutlineGeometry
  22. * @constructor
  23. *
  24. * @param {Object} options Object with the following properties:
  25. * @param {Number} options.length The length of the cylinder.
  26. * @param {Number} options.topRadius The radius of the top of the cylinder.
  27. * @param {Number} options.bottomRadius The radius of the bottom of the cylinder.
  28. * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder.
  29. * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder.
  30. *
  31. * @exception {DeveloperError} options.length must be greater than 0.
  32. * @exception {DeveloperError} options.topRadius must be greater than 0.
  33. * @exception {DeveloperError} options.bottomRadius must be greater than 0.
  34. * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0.
  35. * @exception {DeveloperError} options.slices must be greater than or equal to 3.
  36. *
  37. * @see CylinderOutlineGeometry.createGeometry
  38. *
  39. * @example
  40. * // create cylinder geometry
  41. * var cylinder = new Cesium.CylinderOutlineGeometry({
  42. * length: 200000,
  43. * topRadius: 80000,
  44. * bottomRadius: 200000,
  45. * });
  46. * var geometry = Cesium.CylinderOutlineGeometry.createGeometry(cylinder);
  47. */
  48. function CylinderOutlineGeometry(options) {
  49. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  50. var length = options.length;
  51. var topRadius = options.topRadius;
  52. var bottomRadius = options.bottomRadius;
  53. var slices = defaultValue(options.slices, 128);
  54. var numberOfVerticalLines = Math.max(defaultValue(options.numberOfVerticalLines, 16), 0);
  55. //>>includeStart('debug', pragmas.debug);
  56. Check.typeOf.number('options.positions', length);
  57. Check.typeOf.number('options.topRadius', topRadius);
  58. Check.typeOf.number('options.bottomRadius', bottomRadius);
  59. Check.typeOf.number.greaterThanOrEquals('options.slices', slices, 3);
  60. if (defined(options.offsetAttribute) && options.offsetAttribute === GeometryOffsetAttribute.TOP) {
  61. throw new DeveloperError('GeometryOffsetAttribute.TOP is not a supported options.offsetAttribute for this geometry.');
  62. }
  63. //>>includeEnd('debug');
  64. this._length = length;
  65. this._topRadius = topRadius;
  66. this._bottomRadius = bottomRadius;
  67. this._slices = slices;
  68. this._numberOfVerticalLines = numberOfVerticalLines;
  69. this._offsetAttribute = options.offsetAttribute;
  70. this._workerName = 'createCylinderOutlineGeometry';
  71. }
  72. /**
  73. * The number of elements used to pack the object into an array.
  74. * @type {Number}
  75. */
  76. CylinderOutlineGeometry.packedLength = 6;
  77. /**
  78. * Stores the provided instance into the provided array.
  79. *
  80. * @param {CylinderOutlineGeometry} value The value to pack.
  81. * @param {Number[]} array The array to pack into.
  82. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  83. *
  84. * @returns {Number[]} The array that was packed into
  85. */
  86. CylinderOutlineGeometry.pack = function(value, array, startingIndex) {
  87. //>>includeStart('debug', pragmas.debug);
  88. Check.typeOf.object('value', value);
  89. Check.defined('array', array);
  90. //>>includeEnd('debug');
  91. startingIndex = defaultValue(startingIndex, 0);
  92. array[startingIndex++] = value._length;
  93. array[startingIndex++] = value._topRadius;
  94. array[startingIndex++] = value._bottomRadius;
  95. array[startingIndex++] = value._slices;
  96. array[startingIndex++] = value._numberOfVerticalLines;
  97. array[startingIndex] = defaultValue(value._offsetAttribute, -1);
  98. return array;
  99. };
  100. var scratchOptions = {
  101. length : undefined,
  102. topRadius : undefined,
  103. bottomRadius : undefined,
  104. slices : undefined,
  105. numberOfVerticalLines : undefined,
  106. offsetAttribute : undefined
  107. };
  108. /**
  109. * Retrieves an instance from a packed array.
  110. *
  111. * @param {Number[]} array The packed array.
  112. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  113. * @param {CylinderOutlineGeometry} [result] The object into which to store the result.
  114. * @returns {CylinderOutlineGeometry} The modified result parameter or a new CylinderOutlineGeometry instance if one was not provided.
  115. */
  116. CylinderOutlineGeometry.unpack = function(array, startingIndex, result) {
  117. //>>includeStart('debug', pragmas.debug);
  118. Check.defined('array', array);
  119. //>>includeEnd('debug');
  120. startingIndex = defaultValue(startingIndex, 0);
  121. var length = array[startingIndex++];
  122. var topRadius = array[startingIndex++];
  123. var bottomRadius = array[startingIndex++];
  124. var slices = array[startingIndex++];
  125. var numberOfVerticalLines = array[startingIndex++];
  126. var offsetAttribute = array[startingIndex];
  127. if (!defined(result)) {
  128. scratchOptions.length = length;
  129. scratchOptions.topRadius = topRadius;
  130. scratchOptions.bottomRadius = bottomRadius;
  131. scratchOptions.slices = slices;
  132. scratchOptions.numberOfVerticalLines = numberOfVerticalLines;
  133. scratchOptions.offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  134. return new CylinderOutlineGeometry(scratchOptions);
  135. }
  136. result._length = length;
  137. result._topRadius = topRadius;
  138. result._bottomRadius = bottomRadius;
  139. result._slices = slices;
  140. result._numberOfVerticalLines = numberOfVerticalLines;
  141. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  142. return result;
  143. };
  144. /**
  145. * Computes the geometric representation of an outline of a cylinder, including its vertices, indices, and a bounding sphere.
  146. *
  147. * @param {CylinderOutlineGeometry} cylinderGeometry A description of the cylinder outline.
  148. * @returns {Geometry|undefined} The computed vertices and indices.
  149. */
  150. CylinderOutlineGeometry.createGeometry = function(cylinderGeometry) {
  151. var length = cylinderGeometry._length;
  152. var topRadius = cylinderGeometry._topRadius;
  153. var bottomRadius = cylinderGeometry._bottomRadius;
  154. var slices = cylinderGeometry._slices;
  155. var numberOfVerticalLines = cylinderGeometry._numberOfVerticalLines;
  156. if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) {
  157. return;
  158. }
  159. var numVertices = slices * 2;
  160. var positions = CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, false);
  161. var numIndices = slices * 2;
  162. var numSide;
  163. if (numberOfVerticalLines > 0) {
  164. var numSideLines = Math.min(numberOfVerticalLines, slices);
  165. numSide = Math.round(slices / numSideLines);
  166. numIndices += numSideLines;
  167. }
  168. var indices = IndexDatatype.createTypedArray(numVertices, numIndices * 2);
  169. var index = 0;
  170. var i;
  171. for (i = 0; i < slices - 1; i++) {
  172. indices[index++] = i;
  173. indices[index++] = i + 1;
  174. indices[index++] = i + slices;
  175. indices[index++] = i + 1 + slices;
  176. }
  177. indices[index++] = slices - 1;
  178. indices[index++] = 0;
  179. indices[index++] = slices + slices - 1;
  180. indices[index++] = slices;
  181. if (numberOfVerticalLines > 0) {
  182. for (i = 0; i < slices; i += numSide) {
  183. indices[index++] = i;
  184. indices[index++] = i + slices;
  185. }
  186. }
  187. var attributes = new GeometryAttributes();
  188. attributes.position = new GeometryAttribute({
  189. componentDatatype : ComponentDatatype.DOUBLE,
  190. componentsPerAttribute : 3,
  191. values : positions
  192. });
  193. radiusScratch.x = length * 0.5;
  194. radiusScratch.y = Math.max(bottomRadius, topRadius);
  195. var boundingSphere = new BoundingSphere(Cartesian3.ZERO, Cartesian2.magnitude(radiusScratch));
  196. if (defined(cylinderGeometry._offsetAttribute)) {
  197. length = positions.length;
  198. var applyOffset = new Uint8Array(length / 3);
  199. var offsetValue = cylinderGeometry._offsetAttribute === GeometryOffsetAttribute.NONE ? 0 : 1;
  200. arrayFill(applyOffset, offsetValue);
  201. attributes.applyOffset = new GeometryAttribute({
  202. componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
  203. componentsPerAttribute : 1,
  204. values: applyOffset
  205. });
  206. }
  207. return new Geometry({
  208. attributes : attributes,
  209. indices : indices,
  210. primitiveType : PrimitiveType.LINES,
  211. boundingSphere : boundingSphere,
  212. offsetAttribute : cylinderGeometry._offsetAttribute
  213. });
  214. };
  215. export default CylinderOutlineGeometry;