EllipseOutlineGeometry-cb382d5f.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /**
  2. * Cesium - https://github.com/AnalyticalGraphicsInc/cesium
  3. *
  4. * Copyright 2011-2017 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/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md for full licensing details.
  22. */
  23. define(['exports', './when-8d13db60', './Check-70bec281', './Math-61ede240', './Cartographic-fe4be337', './Cartesian2-85064f09', './BoundingSphere-775c5788', './ComponentDatatype-5862616f', './GeometryAttribute-91704ebb', './PrimitiveType-97893bc7', './GeometryAttributes-aacecde6', './IndexDatatype-9435b55f', './GeometryOffsetAttribute-ca302482', './EllipseGeometryLibrary-08dbcdef'], function (exports, when, Check, _Math, Cartographic, Cartesian2, BoundingSphere, ComponentDatatype, GeometryAttribute, PrimitiveType, GeometryAttributes, IndexDatatype, GeometryOffsetAttribute, EllipseGeometryLibrary) { 'use strict';
  24. var scratchCartesian1 = new Cartographic.Cartesian3();
  25. var boundingSphereCenter = new Cartographic.Cartesian3();
  26. function computeEllipse(options) {
  27. var center = options.center;
  28. boundingSphereCenter = Cartographic.Cartesian3.multiplyByScalar(options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter), options.height, boundingSphereCenter);
  29. boundingSphereCenter = Cartographic.Cartesian3.add(center, boundingSphereCenter, boundingSphereCenter);
  30. var boundingSphere = new BoundingSphere.BoundingSphere(boundingSphereCenter, options.semiMajorAxis);
  31. var positions = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions;
  32. var attributes = new GeometryAttributes.GeometryAttributes({
  33. position: new GeometryAttribute.GeometryAttribute({
  34. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  35. componentsPerAttribute : 3,
  36. values : EllipseGeometryLibrary.EllipseGeometryLibrary.raisePositionsToHeight(positions, options, false)
  37. })
  38. });
  39. var length = positions.length / 3;
  40. var indices = IndexDatatype.IndexDatatype.createTypedArray(length, length * 2);
  41. var index = 0;
  42. for ( var i = 0; i < length; ++i) {
  43. indices[index++] = i;
  44. indices[index++] = (i + 1) % length;
  45. }
  46. return {
  47. boundingSphere : boundingSphere,
  48. attributes : attributes,
  49. indices : indices
  50. };
  51. }
  52. var topBoundingSphere = new BoundingSphere.BoundingSphere();
  53. var bottomBoundingSphere = new BoundingSphere.BoundingSphere();
  54. function computeExtrudedEllipse(options) {
  55. var center = options.center;
  56. var ellipsoid = options.ellipsoid;
  57. var semiMajorAxis = options.semiMajorAxis;
  58. var scaledNormal = Cartographic.Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1), options.height, scratchCartesian1);
  59. topBoundingSphere.center = Cartographic.Cartesian3.add(center, scaledNormal, topBoundingSphere.center);
  60. topBoundingSphere.radius = semiMajorAxis;
  61. scaledNormal = Cartographic.Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center, scaledNormal), options.extrudedHeight, scaledNormal);
  62. bottomBoundingSphere.center = Cartographic.Cartesian3.add(center, scaledNormal, bottomBoundingSphere.center);
  63. bottomBoundingSphere.radius = semiMajorAxis;
  64. var positions = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(options, false, true).outerPositions;
  65. var attributes = new GeometryAttributes.GeometryAttributes({
  66. position: new GeometryAttribute.GeometryAttribute({
  67. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  68. componentsPerAttribute : 3,
  69. values : EllipseGeometryLibrary.EllipseGeometryLibrary.raisePositionsToHeight(positions, options, true)
  70. })
  71. });
  72. positions = attributes.position.values;
  73. var boundingSphere = BoundingSphere.BoundingSphere.union(topBoundingSphere, bottomBoundingSphere);
  74. var length = positions.length/3;
  75. if (when.defined(options.offsetAttribute)) {
  76. var applyOffset = new Uint8Array(length);
  77. if (options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  78. applyOffset = GeometryOffsetAttribute.arrayFill(applyOffset, 1, 0, length / 2);
  79. } else {
  80. var offsetValue = options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  81. applyOffset = GeometryOffsetAttribute.arrayFill(applyOffset, offsetValue);
  82. }
  83. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  84. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  85. componentsPerAttribute : 1,
  86. values: applyOffset
  87. });
  88. }
  89. var numberOfVerticalLines = when.defaultValue(options.numberOfVerticalLines, 16);
  90. numberOfVerticalLines = _Math.CesiumMath.clamp(numberOfVerticalLines, 0, length/2);
  91. var indices = IndexDatatype.IndexDatatype.createTypedArray(length, length * 2 + numberOfVerticalLines * 2);
  92. length /= 2;
  93. var index = 0;
  94. var i;
  95. for (i = 0; i < length; ++i) {
  96. indices[index++] = i;
  97. indices[index++] = (i + 1) % length;
  98. indices[index++] = i + length;
  99. indices[index++] = ((i + 1) % length) + length;
  100. }
  101. var numSide;
  102. if (numberOfVerticalLines > 0) {
  103. var numSideLines = Math.min(numberOfVerticalLines, length);
  104. numSide = Math.round(length / numSideLines);
  105. var maxI = Math.min(numSide * numberOfVerticalLines, length);
  106. for (i = 0; i < maxI; i += numSide) {
  107. indices[index++] = i;
  108. indices[index++] = i + length;
  109. }
  110. }
  111. return {
  112. boundingSphere : boundingSphere,
  113. attributes : attributes,
  114. indices : indices
  115. };
  116. }
  117. /**
  118. * A description of the outline of an ellipse on an ellipsoid.
  119. *
  120. * @alias EllipseOutlineGeometry
  121. * @constructor
  122. *
  123. * @param {Object} options Object with the following properties:
  124. * @param {Cartesian3} options.center The ellipse's center point in the fixed frame.
  125. * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters.
  126. * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters.
  127. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on.
  128. * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface.
  129. * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface.
  130. * @param {Number} [options.rotation=0.0] The angle from north (counter-clockwise) in radians.
  131. * @param {Number} [options.granularity=0.02] The angular distance between points on the ellipse in radians.
  132. * @param {Number} [options.numberOfVerticalLines=16] Number of lines to draw between the top and bottom surface of an extruded ellipse.
  133. *
  134. * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero.
  135. * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis.
  136. * @exception {DeveloperError} granularity must be greater than zero.
  137. *
  138. * @see EllipseOutlineGeometry.createGeometry
  139. *
  140. * @example
  141. * var ellipse = new Cesium.EllipseOutlineGeometry({
  142. * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
  143. * semiMajorAxis : 500000.0,
  144. * semiMinorAxis : 300000.0,
  145. * rotation : Cesium.Math.toRadians(60.0)
  146. * });
  147. * var geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse);
  148. */
  149. function EllipseOutlineGeometry(options) {
  150. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  151. var center = options.center;
  152. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  153. var semiMajorAxis = options.semiMajorAxis;
  154. var semiMinorAxis = options.semiMinorAxis;
  155. var granularity = when.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  156. //>>includeStart('debug', pragmas.debug);
  157. if (!when.defined(center)) {
  158. throw new Check.DeveloperError('center is required.');
  159. }
  160. if (!when.defined(semiMajorAxis)) {
  161. throw new Check.DeveloperError('semiMajorAxis is required.');
  162. }
  163. if (!when.defined(semiMinorAxis)) {
  164. throw new Check.DeveloperError('semiMinorAxis is required.');
  165. }
  166. if (semiMajorAxis < semiMinorAxis) {
  167. throw new Check.DeveloperError('semiMajorAxis must be greater than or equal to the semiMinorAxis.');
  168. }
  169. if (granularity <= 0.0) {
  170. throw new Check.DeveloperError('granularity must be greater than zero.');
  171. }
  172. //>>includeEnd('debug');
  173. var height = when.defaultValue(options.height, 0.0);
  174. var extrudedHeight = when.defaultValue(options.extrudedHeight, height);
  175. this._center = Cartographic.Cartesian3.clone(center);
  176. this._semiMajorAxis = semiMajorAxis;
  177. this._semiMinorAxis = semiMinorAxis;
  178. this._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid);
  179. this._rotation = when.defaultValue(options.rotation, 0.0);
  180. this._height = Math.max(extrudedHeight, height);
  181. this._granularity = granularity;
  182. this._extrudedHeight = Math.min(extrudedHeight, height);
  183. this._numberOfVerticalLines = Math.max(when.defaultValue(options.numberOfVerticalLines, 16), 0);
  184. this._offsetAttribute = options.offsetAttribute;
  185. this._workerName = 'createEllipseOutlineGeometry';
  186. }
  187. /**
  188. * The number of elements used to pack the object into an array.
  189. * @type {Number}
  190. */
  191. EllipseOutlineGeometry.packedLength = Cartographic.Cartesian3.packedLength + Cartesian2.Ellipsoid.packedLength + 8;
  192. /**
  193. * Stores the provided instance into the provided array.
  194. *
  195. * @param {EllipseOutlineGeometry} value The value to pack.
  196. * @param {Number[]} array The array to pack into.
  197. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  198. *
  199. * @returns {Number[]} The array that was packed into
  200. */
  201. EllipseOutlineGeometry.pack = function(value, array, startingIndex) {
  202. //>>includeStart('debug', pragmas.debug);
  203. if (!when.defined(value)) {
  204. throw new Check.DeveloperError('value is required');
  205. }
  206. if (!when.defined(array)) {
  207. throw new Check.DeveloperError('array is required');
  208. }
  209. //>>includeEnd('debug');
  210. startingIndex = when.defaultValue(startingIndex, 0);
  211. Cartographic.Cartesian3.pack(value._center, array, startingIndex);
  212. startingIndex += Cartographic.Cartesian3.packedLength;
  213. Cartesian2.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  214. startingIndex += Cartesian2.Ellipsoid.packedLength;
  215. array[startingIndex++] = value._semiMajorAxis;
  216. array[startingIndex++] = value._semiMinorAxis;
  217. array[startingIndex++] = value._rotation;
  218. array[startingIndex++] = value._height;
  219. array[startingIndex++] = value._granularity;
  220. array[startingIndex++] = value._extrudedHeight;
  221. array[startingIndex++] = value._numberOfVerticalLines;
  222. array[startingIndex] = when.defaultValue(value._offsetAttribute, -1);
  223. return array;
  224. };
  225. var scratchCenter = new Cartographic.Cartesian3();
  226. var scratchEllipsoid = new Cartesian2.Ellipsoid();
  227. var scratchOptions = {
  228. center : scratchCenter,
  229. ellipsoid : scratchEllipsoid,
  230. semiMajorAxis : undefined,
  231. semiMinorAxis : undefined,
  232. rotation : undefined,
  233. height : undefined,
  234. granularity : undefined,
  235. extrudedHeight : undefined,
  236. numberOfVerticalLines : undefined,
  237. offsetAttribute: undefined
  238. };
  239. /**
  240. * Retrieves an instance from a packed array.
  241. *
  242. * @param {Number[]} array The packed array.
  243. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  244. * @param {EllipseOutlineGeometry} [result] The object into which to store the result.
  245. * @returns {EllipseOutlineGeometry} The modified result parameter or a new EllipseOutlineGeometry instance if one was not provided.
  246. */
  247. EllipseOutlineGeometry.unpack = function(array, startingIndex, result) {
  248. //>>includeStart('debug', pragmas.debug);
  249. if (!when.defined(array)) {
  250. throw new Check.DeveloperError('array is required');
  251. }
  252. //>>includeEnd('debug');
  253. startingIndex = when.defaultValue(startingIndex, 0);
  254. var center = Cartographic.Cartesian3.unpack(array, startingIndex, scratchCenter);
  255. startingIndex += Cartographic.Cartesian3.packedLength;
  256. var ellipsoid = Cartesian2.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  257. startingIndex += Cartesian2.Ellipsoid.packedLength;
  258. var semiMajorAxis = array[startingIndex++];
  259. var semiMinorAxis = array[startingIndex++];
  260. var rotation = array[startingIndex++];
  261. var height = array[startingIndex++];
  262. var granularity = array[startingIndex++];
  263. var extrudedHeight = array[startingIndex++];
  264. var numberOfVerticalLines = array[startingIndex++];
  265. var offsetAttribute = array[startingIndex];
  266. if (!when.defined(result)) {
  267. scratchOptions.height = height;
  268. scratchOptions.extrudedHeight = extrudedHeight;
  269. scratchOptions.granularity = granularity;
  270. scratchOptions.rotation = rotation;
  271. scratchOptions.semiMajorAxis = semiMajorAxis;
  272. scratchOptions.semiMinorAxis = semiMinorAxis;
  273. scratchOptions.numberOfVerticalLines = numberOfVerticalLines;
  274. scratchOptions.offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  275. return new EllipseOutlineGeometry(scratchOptions);
  276. }
  277. result._center = Cartographic.Cartesian3.clone(center, result._center);
  278. result._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  279. result._semiMajorAxis = semiMajorAxis;
  280. result._semiMinorAxis = semiMinorAxis;
  281. result._rotation = rotation;
  282. result._height = height;
  283. result._granularity = granularity;
  284. result._extrudedHeight = extrudedHeight;
  285. result._numberOfVerticalLines = numberOfVerticalLines;
  286. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  287. return result;
  288. };
  289. /**
  290. * Computes the geometric representation of an outline of an ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere.
  291. *
  292. * @param {EllipseOutlineGeometry} ellipseGeometry A description of the ellipse.
  293. * @returns {Geometry|undefined} The computed vertices and indices.
  294. */
  295. EllipseOutlineGeometry.createGeometry = function(ellipseGeometry) {
  296. if ((ellipseGeometry._semiMajorAxis <= 0.0) || (ellipseGeometry._semiMinorAxis <= 0.0)) {
  297. return;
  298. }
  299. var height = ellipseGeometry._height;
  300. var extrudedHeight = ellipseGeometry._extrudedHeight;
  301. var extrude = !_Math.CesiumMath.equalsEpsilon(height, extrudedHeight, 0, _Math.CesiumMath.EPSILON2);
  302. ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(ellipseGeometry._center, ellipseGeometry._center);
  303. var options = {
  304. center : ellipseGeometry._center,
  305. semiMajorAxis : ellipseGeometry._semiMajorAxis,
  306. semiMinorAxis : ellipseGeometry._semiMinorAxis,
  307. ellipsoid : ellipseGeometry._ellipsoid,
  308. rotation : ellipseGeometry._rotation,
  309. height : height,
  310. granularity : ellipseGeometry._granularity,
  311. numberOfVerticalLines : ellipseGeometry._numberOfVerticalLines
  312. };
  313. var geometry;
  314. if (extrude) {
  315. options.extrudedHeight = extrudedHeight;
  316. options.offsetAttribute = ellipseGeometry._offsetAttribute;
  317. geometry = computeExtrudedEllipse(options);
  318. } else {
  319. geometry = computeEllipse(options);
  320. if (when.defined(ellipseGeometry._offsetAttribute)) {
  321. var length = geometry.attributes.position.values.length;
  322. var applyOffset = new Uint8Array(length / 3);
  323. var offsetValue = ellipseGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  324. GeometryOffsetAttribute.arrayFill(applyOffset, offsetValue);
  325. geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  326. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  327. componentsPerAttribute : 1,
  328. values: applyOffset
  329. });
  330. }
  331. }
  332. return new GeometryAttribute.Geometry({
  333. attributes : geometry.attributes,
  334. indices : geometry.indices,
  335. primitiveType : PrimitiveType.PrimitiveType.LINES,
  336. boundingSphere : geometry.boundingSphere,
  337. offsetAttribute : ellipseGeometry._offsetAttribute
  338. });
  339. };
  340. exports.EllipseOutlineGeometry = EllipseOutlineGeometry;
  341. });