createCylinderOutlineGeometry.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /**
  2. * Cesium - https://github.com/CesiumGS/cesium
  3. *
  4. * Copyright 2011-2020 Cesium Contributors
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Columbus View (Pat. Pend.)
  19. *
  20. * Portions licensed separately.
  21. * See https://github.com/CesiumGS/cesium/blob/master/LICENSE.md for full licensing details.
  22. */
  23. define(['./when-8d13db60', './Check-70bec281', './Math-61ede240', './Cartographic-fe4be337', './Cartesian4-5af5bb24', './arrayFill-9766fb2e', './Cartesian2-85064f09', './BoundingSphere-8f8a682c', './RuntimeError-ba10bc3e', './WebGLConstants-4c11ee5f', './ComponentDatatype-5862616f', './GeometryAttribute-ed9d707f', './PrimitiveType-97893bc7', './FeatureDetection-7bd32c34', './Transforms-878b6816', './buildModuleUrl-e7952659', './GeometryAttributes-aacecde6', './GeometryOffsetAttribute-999fc023', './IndexDatatype-9435b55f', './CylinderGeometryLibrary-8c0fda9f'], function (when, Check, _Math, Cartographic, Cartesian4, arrayFill, Cartesian2, BoundingSphere, RuntimeError, WebGLConstants, ComponentDatatype, GeometryAttribute, PrimitiveType, FeatureDetection, Transforms, buildModuleUrl, GeometryAttributes, GeometryOffsetAttribute, IndexDatatype, CylinderGeometryLibrary) { 'use strict';
  24. var radiusScratch = new Cartesian2.Cartesian2();
  25. /**
  26. * A description of the outline of a cylinder.
  27. *
  28. * @alias CylinderOutlineGeometry
  29. * @constructor
  30. *
  31. * @param {Object} options Object with the following properties:
  32. * @param {Number} options.length The length of the cylinder.
  33. * @param {Number} options.topRadius The radius of the top of the cylinder.
  34. * @param {Number} options.bottomRadius The radius of the bottom of the cylinder.
  35. * @param {Number} [options.slices=128] The number of edges around the perimeter of the cylinder.
  36. * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surfaces of the cylinder.
  37. *
  38. * @exception {DeveloperError} options.length must be greater than 0.
  39. * @exception {DeveloperError} options.topRadius must be greater than 0.
  40. * @exception {DeveloperError} options.bottomRadius must be greater than 0.
  41. * @exception {DeveloperError} bottomRadius and topRadius cannot both equal 0.
  42. * @exception {DeveloperError} options.slices must be greater than or equal to 3.
  43. *
  44. * @see CylinderOutlineGeometry.createGeometry
  45. *
  46. * @example
  47. * // create cylinder geometry
  48. * var cylinder = new Cesium.CylinderOutlineGeometry({
  49. * length: 200000,
  50. * topRadius: 80000,
  51. * bottomRadius: 200000,
  52. * });
  53. * var geometry = Cesium.CylinderOutlineGeometry.createGeometry(cylinder);
  54. */
  55. function CylinderOutlineGeometry(options) {
  56. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  57. var length = options.length;
  58. var topRadius = options.topRadius;
  59. var bottomRadius = options.bottomRadius;
  60. var slices = when.defaultValue(options.slices, 128);
  61. var numberOfVerticalLines = Math.max(when.defaultValue(options.numberOfVerticalLines, 16), 0);
  62. //>>includeStart('debug', pragmas.debug);
  63. Check.Check.typeOf.number('options.positions', length);
  64. Check.Check.typeOf.number('options.topRadius', topRadius);
  65. Check.Check.typeOf.number('options.bottomRadius', bottomRadius);
  66. Check.Check.typeOf.number.greaterThanOrEquals('options.slices', slices, 3);
  67. if (when.defined(options.offsetAttribute) && options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  68. throw new Check.DeveloperError('GeometryOffsetAttribute.TOP is not a supported options.offsetAttribute for this geometry.');
  69. }
  70. //>>includeEnd('debug');
  71. this._length = length;
  72. this._topRadius = topRadius;
  73. this._bottomRadius = bottomRadius;
  74. this._slices = slices;
  75. this._numberOfVerticalLines = numberOfVerticalLines;
  76. this._offsetAttribute = options.offsetAttribute;
  77. this._workerName = 'createCylinderOutlineGeometry';
  78. }
  79. /**
  80. * The number of elements used to pack the object into an array.
  81. * @type {Number}
  82. */
  83. CylinderOutlineGeometry.packedLength = 6;
  84. /**
  85. * Stores the provided instance into the provided array.
  86. *
  87. * @param {CylinderOutlineGeometry} value The value to pack.
  88. * @param {Number[]} array The array to pack into.
  89. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  90. *
  91. * @returns {Number[]} The array that was packed into
  92. */
  93. CylinderOutlineGeometry.pack = function(value, array, startingIndex) {
  94. //>>includeStart('debug', pragmas.debug);
  95. Check.Check.typeOf.object('value', value);
  96. Check.Check.defined('array', array);
  97. //>>includeEnd('debug');
  98. startingIndex = when.defaultValue(startingIndex, 0);
  99. array[startingIndex++] = value._length;
  100. array[startingIndex++] = value._topRadius;
  101. array[startingIndex++] = value._bottomRadius;
  102. array[startingIndex++] = value._slices;
  103. array[startingIndex++] = value._numberOfVerticalLines;
  104. array[startingIndex] = when.defaultValue(value._offsetAttribute, -1);
  105. return array;
  106. };
  107. var scratchOptions = {
  108. length : undefined,
  109. topRadius : undefined,
  110. bottomRadius : undefined,
  111. slices : undefined,
  112. numberOfVerticalLines : undefined,
  113. offsetAttribute : undefined
  114. };
  115. /**
  116. * Retrieves an instance from a packed array.
  117. *
  118. * @param {Number[]} array The packed array.
  119. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  120. * @param {CylinderOutlineGeometry} [result] The object into which to store the result.
  121. * @returns {CylinderOutlineGeometry} The modified result parameter or a new CylinderOutlineGeometry instance if one was not provided.
  122. */
  123. CylinderOutlineGeometry.unpack = function(array, startingIndex, result) {
  124. //>>includeStart('debug', pragmas.debug);
  125. Check.Check.defined('array', array);
  126. //>>includeEnd('debug');
  127. startingIndex = when.defaultValue(startingIndex, 0);
  128. var length = array[startingIndex++];
  129. var topRadius = array[startingIndex++];
  130. var bottomRadius = array[startingIndex++];
  131. var slices = array[startingIndex++];
  132. var numberOfVerticalLines = array[startingIndex++];
  133. var offsetAttribute = array[startingIndex];
  134. if (!when.defined(result)) {
  135. scratchOptions.length = length;
  136. scratchOptions.topRadius = topRadius;
  137. scratchOptions.bottomRadius = bottomRadius;
  138. scratchOptions.slices = slices;
  139. scratchOptions.numberOfVerticalLines = numberOfVerticalLines;
  140. scratchOptions.offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  141. return new CylinderOutlineGeometry(scratchOptions);
  142. }
  143. result._length = length;
  144. result._topRadius = topRadius;
  145. result._bottomRadius = bottomRadius;
  146. result._slices = slices;
  147. result._numberOfVerticalLines = numberOfVerticalLines;
  148. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  149. return result;
  150. };
  151. /**
  152. * Computes the geometric representation of an outline of a cylinder, including its vertices, indices, and a bounding sphere.
  153. *
  154. * @param {CylinderOutlineGeometry} cylinderGeometry A description of the cylinder outline.
  155. * @returns {Geometry|undefined} The computed vertices and indices.
  156. */
  157. CylinderOutlineGeometry.createGeometry = function(cylinderGeometry) {
  158. var length = cylinderGeometry._length;
  159. var topRadius = cylinderGeometry._topRadius;
  160. var bottomRadius = cylinderGeometry._bottomRadius;
  161. var slices = cylinderGeometry._slices;
  162. var numberOfVerticalLines = cylinderGeometry._numberOfVerticalLines;
  163. if ((length <= 0) || (topRadius < 0) || (bottomRadius < 0) || ((topRadius === 0) && (bottomRadius === 0))) {
  164. return;
  165. }
  166. var numVertices = slices * 2;
  167. var positions = CylinderGeometryLibrary.CylinderGeometryLibrary.computePositions(length, topRadius, bottomRadius, slices, false);
  168. var numIndices = slices * 2;
  169. var numSide;
  170. if (numberOfVerticalLines > 0) {
  171. var numSideLines = Math.min(numberOfVerticalLines, slices);
  172. numSide = Math.round(slices / numSideLines);
  173. numIndices += numSideLines;
  174. }
  175. var indices = IndexDatatype.IndexDatatype.createTypedArray(numVertices, numIndices * 2);
  176. var index = 0;
  177. var i;
  178. for (i = 0; i < slices - 1; i++) {
  179. indices[index++] = i;
  180. indices[index++] = i + 1;
  181. indices[index++] = i + slices;
  182. indices[index++] = i + 1 + slices;
  183. }
  184. indices[index++] = slices - 1;
  185. indices[index++] = 0;
  186. indices[index++] = slices + slices - 1;
  187. indices[index++] = slices;
  188. if (numberOfVerticalLines > 0) {
  189. for (i = 0; i < slices; i += numSide) {
  190. indices[index++] = i;
  191. indices[index++] = i + slices;
  192. }
  193. }
  194. var attributes = new GeometryAttributes.GeometryAttributes();
  195. attributes.position = new GeometryAttribute.GeometryAttribute({
  196. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  197. componentsPerAttribute : 3,
  198. values : positions
  199. });
  200. radiusScratch.x = length * 0.5;
  201. radiusScratch.y = Math.max(bottomRadius, topRadius);
  202. var boundingSphere = new BoundingSphere.BoundingSphere(Cartographic.Cartesian3.ZERO, Cartesian2.Cartesian2.magnitude(radiusScratch));
  203. if (when.defined(cylinderGeometry._offsetAttribute)) {
  204. length = positions.length;
  205. var applyOffset = new Uint8Array(length / 3);
  206. var offsetValue = cylinderGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  207. arrayFill.arrayFill(applyOffset, offsetValue);
  208. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  209. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  210. componentsPerAttribute : 1,
  211. values: applyOffset
  212. });
  213. }
  214. return new GeometryAttribute.Geometry({
  215. attributes : attributes,
  216. indices : indices,
  217. primitiveType : PrimitiveType.PrimitiveType.LINES,
  218. boundingSphere : boundingSphere,
  219. offsetAttribute : cylinderGeometry._offsetAttribute
  220. });
  221. };
  222. function createCylinderOutlineGeometry(cylinderGeometry, offset) {
  223. if (when.defined(offset)) {
  224. cylinderGeometry = CylinderOutlineGeometry.unpack(cylinderGeometry, offset);
  225. }
  226. return CylinderOutlineGeometry.createGeometry(cylinderGeometry);
  227. }
  228. return createCylinderOutlineGeometry;
  229. });