createCylinderOutlineGeometry.js 9.9 KB

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