EllipseGeometry-11a378e8.js 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './when-e6985d2a', './Check-24cae389', './Math-392d0035', './Cartesian2-a5d6dde9', './Transforms-81680c41', './ComponentDatatype-cb08e294', './GeometryAttribute-6d403cd9', './GeometryAttributes-d6ea8c2b', './GeometryPipeline-e8a01ba6', './IndexDatatype-1be7d1f8', './GeometryOffsetAttribute-9c46b133', './VertexFormat-2df57ea4', './EllipseGeometryLibrary-5e06d338', './GeometryInstance-252acf0f'], function (exports, when, Check, _Math, Cartesian2, Transforms, ComponentDatatype, GeometryAttribute, GeometryAttributes, GeometryPipeline, IndexDatatype, GeometryOffsetAttribute, VertexFormat, EllipseGeometryLibrary, GeometryInstance) { 'use strict';
  3. var scratchCartesian1 = new Cartesian2.Cartesian3();
  4. var scratchCartesian2 = new Cartesian2.Cartesian3();
  5. var scratchCartesian3 = new Cartesian2.Cartesian3();
  6. var scratchCartesian4 = new Cartesian2.Cartesian3();
  7. var texCoordScratch = new Cartesian2.Cartesian2();
  8. var textureMatrixScratch = new Transforms.Matrix3();
  9. var tangentMatrixScratch = new Transforms.Matrix3();
  10. var quaternionScratch = new Transforms.Quaternion();
  11. var scratchNormal = new Cartesian2.Cartesian3();
  12. var scratchTangent = new Cartesian2.Cartesian3();
  13. var scratchBitangent = new Cartesian2.Cartesian3();
  14. var scratchCartographic = new Cartesian2.Cartographic();
  15. var projectedCenterScratch = new Cartesian2.Cartesian3();
  16. var scratchMinTexCoord = new Cartesian2.Cartesian2();
  17. var scratchMaxTexCoord = new Cartesian2.Cartesian2();
  18. function computeTopBottomAttributes(positions, options, extrude) {
  19. var vertexFormat = options.vertexFormat;
  20. var center = options.center;
  21. var semiMajorAxis = options.semiMajorAxis;
  22. var semiMinorAxis = options.semiMinorAxis;
  23. var ellipsoid = options.ellipsoid;
  24. var stRotation = options.stRotation;
  25. var size = extrude ? (positions.length / 3) * 2 : positions.length / 3;
  26. var shadowVolume = options.shadowVolume;
  27. var textureCoordinates = vertexFormat.st
  28. ? new Float32Array(size * 2)
  29. : undefined;
  30. var normals = vertexFormat.normal ? new Float32Array(size * 3) : undefined;
  31. var tangents = vertexFormat.tangent ? new Float32Array(size * 3) : undefined;
  32. var bitangents = vertexFormat.bitangent
  33. ? new Float32Array(size * 3)
  34. : undefined;
  35. var extrudeNormals = shadowVolume ? new Float32Array(size * 3) : undefined;
  36. var textureCoordIndex = 0;
  37. // Raise positions to a height above the ellipsoid and compute the
  38. // texture coordinates, normals, tangents, and bitangents.
  39. var normal = scratchNormal;
  40. var tangent = scratchTangent;
  41. var bitangent = scratchBitangent;
  42. var projection = new Transforms.GeographicProjection(ellipsoid);
  43. var projectedCenter = projection.project(
  44. ellipsoid.cartesianToCartographic(center, scratchCartographic),
  45. projectedCenterScratch
  46. );
  47. var geodeticNormal = ellipsoid.scaleToGeodeticSurface(
  48. center,
  49. scratchCartesian1
  50. );
  51. ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal);
  52. var textureMatrix = textureMatrixScratch;
  53. var tangentMatrix = tangentMatrixScratch;
  54. if (stRotation !== 0) {
  55. var rotation = Transforms.Quaternion.fromAxisAngle(
  56. geodeticNormal,
  57. stRotation,
  58. quaternionScratch
  59. );
  60. textureMatrix = Transforms.Matrix3.fromQuaternion(rotation, textureMatrix);
  61. rotation = Transforms.Quaternion.fromAxisAngle(
  62. geodeticNormal,
  63. -stRotation,
  64. quaternionScratch
  65. );
  66. tangentMatrix = Transforms.Matrix3.fromQuaternion(rotation, tangentMatrix);
  67. } else {
  68. textureMatrix = Transforms.Matrix3.clone(Transforms.Matrix3.IDENTITY, textureMatrix);
  69. tangentMatrix = Transforms.Matrix3.clone(Transforms.Matrix3.IDENTITY, tangentMatrix);
  70. }
  71. var minTexCoord = Cartesian2.Cartesian2.fromElements(
  72. Number.POSITIVE_INFINITY,
  73. Number.POSITIVE_INFINITY,
  74. scratchMinTexCoord
  75. );
  76. var maxTexCoord = Cartesian2.Cartesian2.fromElements(
  77. Number.NEGATIVE_INFINITY,
  78. Number.NEGATIVE_INFINITY,
  79. scratchMaxTexCoord
  80. );
  81. var length = positions.length;
  82. var bottomOffset = extrude ? length : 0;
  83. var stOffset = (bottomOffset / 3) * 2;
  84. for (var i = 0; i < length; i += 3) {
  85. var i1 = i + 1;
  86. var i2 = i + 2;
  87. var position = Cartesian2.Cartesian3.fromArray(positions, i, scratchCartesian1);
  88. if (vertexFormat.st) {
  89. var rotatedPoint = Transforms.Matrix3.multiplyByVector(
  90. textureMatrix,
  91. position,
  92. scratchCartesian2
  93. );
  94. var projectedPoint = projection.project(
  95. ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic),
  96. scratchCartesian3
  97. );
  98. Cartesian2.Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint);
  99. texCoordScratch.x =
  100. (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis);
  101. texCoordScratch.y =
  102. (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis);
  103. minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x);
  104. minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y);
  105. maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x);
  106. maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y);
  107. if (extrude) {
  108. textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x;
  109. textureCoordinates[textureCoordIndex + 1 + stOffset] =
  110. texCoordScratch.y;
  111. }
  112. textureCoordinates[textureCoordIndex++] = texCoordScratch.x;
  113. textureCoordinates[textureCoordIndex++] = texCoordScratch.y;
  114. }
  115. if (
  116. vertexFormat.normal ||
  117. vertexFormat.tangent ||
  118. vertexFormat.bitangent ||
  119. shadowVolume
  120. ) {
  121. normal = ellipsoid.geodeticSurfaceNormal(position, normal);
  122. if (shadowVolume) {
  123. extrudeNormals[i + bottomOffset] = -normal.x;
  124. extrudeNormals[i1 + bottomOffset] = -normal.y;
  125. extrudeNormals[i2 + bottomOffset] = -normal.z;
  126. }
  127. if (
  128. vertexFormat.normal ||
  129. vertexFormat.tangent ||
  130. vertexFormat.bitangent
  131. ) {
  132. if (vertexFormat.tangent || vertexFormat.bitangent) {
  133. tangent = Cartesian2.Cartesian3.normalize(
  134. Cartesian2.Cartesian3.cross(Cartesian2.Cartesian3.UNIT_Z, normal, tangent),
  135. tangent
  136. );
  137. Transforms.Matrix3.multiplyByVector(tangentMatrix, tangent, tangent);
  138. }
  139. if (vertexFormat.normal) {
  140. normals[i] = normal.x;
  141. normals[i1] = normal.y;
  142. normals[i2] = normal.z;
  143. if (extrude) {
  144. normals[i + bottomOffset] = -normal.x;
  145. normals[i1 + bottomOffset] = -normal.y;
  146. normals[i2 + bottomOffset] = -normal.z;
  147. }
  148. }
  149. if (vertexFormat.tangent) {
  150. tangents[i] = tangent.x;
  151. tangents[i1] = tangent.y;
  152. tangents[i2] = tangent.z;
  153. if (extrude) {
  154. tangents[i + bottomOffset] = -tangent.x;
  155. tangents[i1 + bottomOffset] = -tangent.y;
  156. tangents[i2 + bottomOffset] = -tangent.z;
  157. }
  158. }
  159. if (vertexFormat.bitangent) {
  160. bitangent = Cartesian2.Cartesian3.normalize(
  161. Cartesian2.Cartesian3.cross(normal, tangent, bitangent),
  162. bitangent
  163. );
  164. bitangents[i] = bitangent.x;
  165. bitangents[i1] = bitangent.y;
  166. bitangents[i2] = bitangent.z;
  167. if (extrude) {
  168. bitangents[i + bottomOffset] = bitangent.x;
  169. bitangents[i1 + bottomOffset] = bitangent.y;
  170. bitangents[i2 + bottomOffset] = bitangent.z;
  171. }
  172. }
  173. }
  174. }
  175. }
  176. if (vertexFormat.st) {
  177. length = textureCoordinates.length;
  178. for (var k = 0; k < length; k += 2) {
  179. textureCoordinates[k] =
  180. (textureCoordinates[k] - minTexCoord.x) /
  181. (maxTexCoord.x - minTexCoord.x);
  182. textureCoordinates[k + 1] =
  183. (textureCoordinates[k + 1] - minTexCoord.y) /
  184. (maxTexCoord.y - minTexCoord.y);
  185. }
  186. }
  187. var attributes = new GeometryAttributes.GeometryAttributes();
  188. if (vertexFormat.position) {
  189. var finalPositions = EllipseGeometryLibrary.EllipseGeometryLibrary.raisePositionsToHeight(
  190. positions,
  191. options,
  192. extrude
  193. );
  194. attributes.position = new GeometryAttribute.GeometryAttribute({
  195. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  196. componentsPerAttribute: 3,
  197. values: finalPositions,
  198. });
  199. }
  200. if (vertexFormat.st) {
  201. attributes.st = new GeometryAttribute.GeometryAttribute({
  202. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  203. componentsPerAttribute: 2,
  204. values: textureCoordinates,
  205. });
  206. }
  207. if (vertexFormat.normal) {
  208. attributes.normal = new GeometryAttribute.GeometryAttribute({
  209. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  210. componentsPerAttribute: 3,
  211. values: normals,
  212. });
  213. }
  214. if (vertexFormat.tangent) {
  215. attributes.tangent = new GeometryAttribute.GeometryAttribute({
  216. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  217. componentsPerAttribute: 3,
  218. values: tangents,
  219. });
  220. }
  221. if (vertexFormat.bitangent) {
  222. attributes.bitangent = new GeometryAttribute.GeometryAttribute({
  223. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  224. componentsPerAttribute: 3,
  225. values: bitangents,
  226. });
  227. }
  228. if (shadowVolume) {
  229. attributes.extrudeDirection = new GeometryAttribute.GeometryAttribute({
  230. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  231. componentsPerAttribute: 3,
  232. values: extrudeNormals,
  233. });
  234. }
  235. if (extrude && when.defined(options.offsetAttribute)) {
  236. var offsetAttribute = new Uint8Array(size);
  237. if (options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  238. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, 1, 0, size / 2);
  239. } else {
  240. var offsetValue =
  241. options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  242. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, offsetValue);
  243. }
  244. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  245. componentDatatype: ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  246. componentsPerAttribute: 1,
  247. values: offsetAttribute,
  248. });
  249. }
  250. return attributes;
  251. }
  252. function topIndices(numPts) {
  253. // numTriangles in half = 3 + 8 + 12 + ... = -1 + 4 + (4 + 4) + (4 + 4 + 4) + ... = -1 + 4 * (1 + 2 + 3 + ...)
  254. // = -1 + 4 * ((n * ( n + 1)) / 2)
  255. // total triangles = 2 * numTrangles in half
  256. // indices = total triangles * 3;
  257. // Substitute numPts for n above
  258. var indices = new Array(12 * (numPts * (numPts + 1)) - 6);
  259. var indicesIndex = 0;
  260. var prevIndex;
  261. var numInterior;
  262. var positionIndex;
  263. var i;
  264. var j;
  265. // Indices triangles to the 'right' of the north vector
  266. prevIndex = 0;
  267. positionIndex = 1;
  268. for (i = 0; i < 3; i++) {
  269. indices[indicesIndex++] = positionIndex++;
  270. indices[indicesIndex++] = prevIndex;
  271. indices[indicesIndex++] = positionIndex;
  272. }
  273. for (i = 2; i < numPts + 1; ++i) {
  274. positionIndex = i * (i + 1) - 1;
  275. prevIndex = (i - 1) * i - 1;
  276. indices[indicesIndex++] = positionIndex++;
  277. indices[indicesIndex++] = prevIndex;
  278. indices[indicesIndex++] = positionIndex;
  279. numInterior = 2 * i;
  280. for (j = 0; j < numInterior - 1; ++j) {
  281. indices[indicesIndex++] = positionIndex;
  282. indices[indicesIndex++] = prevIndex++;
  283. indices[indicesIndex++] = prevIndex;
  284. indices[indicesIndex++] = positionIndex++;
  285. indices[indicesIndex++] = prevIndex;
  286. indices[indicesIndex++] = positionIndex;
  287. }
  288. indices[indicesIndex++] = positionIndex++;
  289. indices[indicesIndex++] = prevIndex;
  290. indices[indicesIndex++] = positionIndex;
  291. }
  292. // Indices for center column of triangles
  293. numInterior = numPts * 2;
  294. ++positionIndex;
  295. ++prevIndex;
  296. for (i = 0; i < numInterior - 1; ++i) {
  297. indices[indicesIndex++] = positionIndex;
  298. indices[indicesIndex++] = prevIndex++;
  299. indices[indicesIndex++] = prevIndex;
  300. indices[indicesIndex++] = positionIndex++;
  301. indices[indicesIndex++] = prevIndex;
  302. indices[indicesIndex++] = positionIndex;
  303. }
  304. indices[indicesIndex++] = positionIndex;
  305. indices[indicesIndex++] = prevIndex++;
  306. indices[indicesIndex++] = prevIndex;
  307. indices[indicesIndex++] = positionIndex++;
  308. indices[indicesIndex++] = prevIndex++;
  309. indices[indicesIndex++] = prevIndex;
  310. // Reverse the process creating indices to the 'left' of the north vector
  311. ++prevIndex;
  312. for (i = numPts - 1; i > 1; --i) {
  313. indices[indicesIndex++] = prevIndex++;
  314. indices[indicesIndex++] = prevIndex;
  315. indices[indicesIndex++] = positionIndex;
  316. numInterior = 2 * i;
  317. for (j = 0; j < numInterior - 1; ++j) {
  318. indices[indicesIndex++] = positionIndex;
  319. indices[indicesIndex++] = prevIndex++;
  320. indices[indicesIndex++] = prevIndex;
  321. indices[indicesIndex++] = positionIndex++;
  322. indices[indicesIndex++] = prevIndex;
  323. indices[indicesIndex++] = positionIndex;
  324. }
  325. indices[indicesIndex++] = prevIndex++;
  326. indices[indicesIndex++] = prevIndex++;
  327. indices[indicesIndex++] = positionIndex++;
  328. }
  329. for (i = 0; i < 3; i++) {
  330. indices[indicesIndex++] = prevIndex++;
  331. indices[indicesIndex++] = prevIndex;
  332. indices[indicesIndex++] = positionIndex;
  333. }
  334. return indices;
  335. }
  336. var boundingSphereCenter = new Cartesian2.Cartesian3();
  337. function computeEllipse(options) {
  338. var center = options.center;
  339. boundingSphereCenter = Cartesian2.Cartesian3.multiplyByScalar(
  340. options.ellipsoid.geodeticSurfaceNormal(center, boundingSphereCenter),
  341. options.height,
  342. boundingSphereCenter
  343. );
  344. boundingSphereCenter = Cartesian2.Cartesian3.add(
  345. center,
  346. boundingSphereCenter,
  347. boundingSphereCenter
  348. );
  349. var boundingSphere = new Transforms.BoundingSphere(
  350. boundingSphereCenter,
  351. options.semiMajorAxis
  352. );
  353. var cep = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(
  354. options,
  355. true,
  356. false
  357. );
  358. var positions = cep.positions;
  359. var numPts = cep.numPts;
  360. var attributes = computeTopBottomAttributes(positions, options, false);
  361. var indices = topIndices(numPts);
  362. indices = IndexDatatype.IndexDatatype.createTypedArray(positions.length / 3, indices);
  363. return {
  364. boundingSphere: boundingSphere,
  365. attributes: attributes,
  366. indices: indices,
  367. };
  368. }
  369. function computeWallAttributes(positions, options) {
  370. var vertexFormat = options.vertexFormat;
  371. var center = options.center;
  372. var semiMajorAxis = options.semiMajorAxis;
  373. var semiMinorAxis = options.semiMinorAxis;
  374. var ellipsoid = options.ellipsoid;
  375. var height = options.height;
  376. var extrudedHeight = options.extrudedHeight;
  377. var stRotation = options.stRotation;
  378. var size = (positions.length / 3) * 2;
  379. var finalPositions = new Float64Array(size * 3);
  380. var textureCoordinates = vertexFormat.st
  381. ? new Float32Array(size * 2)
  382. : undefined;
  383. var normals = vertexFormat.normal ? new Float32Array(size * 3) : undefined;
  384. var tangents = vertexFormat.tangent ? new Float32Array(size * 3) : undefined;
  385. var bitangents = vertexFormat.bitangent
  386. ? new Float32Array(size * 3)
  387. : undefined;
  388. var shadowVolume = options.shadowVolume;
  389. var extrudeNormals = shadowVolume ? new Float32Array(size * 3) : undefined;
  390. var textureCoordIndex = 0;
  391. // Raise positions to a height above the ellipsoid and compute the
  392. // texture coordinates, normals, tangents, and bitangents.
  393. var normal = scratchNormal;
  394. var tangent = scratchTangent;
  395. var bitangent = scratchBitangent;
  396. var projection = new Transforms.GeographicProjection(ellipsoid);
  397. var projectedCenter = projection.project(
  398. ellipsoid.cartesianToCartographic(center, scratchCartographic),
  399. projectedCenterScratch
  400. );
  401. var geodeticNormal = ellipsoid.scaleToGeodeticSurface(
  402. center,
  403. scratchCartesian1
  404. );
  405. ellipsoid.geodeticSurfaceNormal(geodeticNormal, geodeticNormal);
  406. var rotation = Transforms.Quaternion.fromAxisAngle(
  407. geodeticNormal,
  408. stRotation,
  409. quaternionScratch
  410. );
  411. var textureMatrix = Transforms.Matrix3.fromQuaternion(rotation, textureMatrixScratch);
  412. var minTexCoord = Cartesian2.Cartesian2.fromElements(
  413. Number.POSITIVE_INFINITY,
  414. Number.POSITIVE_INFINITY,
  415. scratchMinTexCoord
  416. );
  417. var maxTexCoord = Cartesian2.Cartesian2.fromElements(
  418. Number.NEGATIVE_INFINITY,
  419. Number.NEGATIVE_INFINITY,
  420. scratchMaxTexCoord
  421. );
  422. var length = positions.length;
  423. var stOffset = (length / 3) * 2;
  424. for (var i = 0; i < length; i += 3) {
  425. var i1 = i + 1;
  426. var i2 = i + 2;
  427. var position = Cartesian2.Cartesian3.fromArray(positions, i, scratchCartesian1);
  428. var extrudedPosition;
  429. if (vertexFormat.st) {
  430. var rotatedPoint = Transforms.Matrix3.multiplyByVector(
  431. textureMatrix,
  432. position,
  433. scratchCartesian2
  434. );
  435. var projectedPoint = projection.project(
  436. ellipsoid.cartesianToCartographic(rotatedPoint, scratchCartographic),
  437. scratchCartesian3
  438. );
  439. Cartesian2.Cartesian3.subtract(projectedPoint, projectedCenter, projectedPoint);
  440. texCoordScratch.x =
  441. (projectedPoint.x + semiMajorAxis) / (2.0 * semiMajorAxis);
  442. texCoordScratch.y =
  443. (projectedPoint.y + semiMinorAxis) / (2.0 * semiMinorAxis);
  444. minTexCoord.x = Math.min(texCoordScratch.x, minTexCoord.x);
  445. minTexCoord.y = Math.min(texCoordScratch.y, minTexCoord.y);
  446. maxTexCoord.x = Math.max(texCoordScratch.x, maxTexCoord.x);
  447. maxTexCoord.y = Math.max(texCoordScratch.y, maxTexCoord.y);
  448. textureCoordinates[textureCoordIndex + stOffset] = texCoordScratch.x;
  449. textureCoordinates[textureCoordIndex + 1 + stOffset] = texCoordScratch.y;
  450. textureCoordinates[textureCoordIndex++] = texCoordScratch.x;
  451. textureCoordinates[textureCoordIndex++] = texCoordScratch.y;
  452. }
  453. position = ellipsoid.scaleToGeodeticSurface(position, position);
  454. extrudedPosition = Cartesian2.Cartesian3.clone(position, scratchCartesian2);
  455. normal = ellipsoid.geodeticSurfaceNormal(position, normal);
  456. if (shadowVolume) {
  457. extrudeNormals[i + length] = -normal.x;
  458. extrudeNormals[i1 + length] = -normal.y;
  459. extrudeNormals[i2 + length] = -normal.z;
  460. }
  461. var scaledNormal = Cartesian2.Cartesian3.multiplyByScalar(
  462. normal,
  463. height,
  464. scratchCartesian4
  465. );
  466. position = Cartesian2.Cartesian3.add(position, scaledNormal, position);
  467. scaledNormal = Cartesian2.Cartesian3.multiplyByScalar(
  468. normal,
  469. extrudedHeight,
  470. scaledNormal
  471. );
  472. extrudedPosition = Cartesian2.Cartesian3.add(
  473. extrudedPosition,
  474. scaledNormal,
  475. extrudedPosition
  476. );
  477. if (vertexFormat.position) {
  478. finalPositions[i + length] = extrudedPosition.x;
  479. finalPositions[i1 + length] = extrudedPosition.y;
  480. finalPositions[i2 + length] = extrudedPosition.z;
  481. finalPositions[i] = position.x;
  482. finalPositions[i1] = position.y;
  483. finalPositions[i2] = position.z;
  484. }
  485. if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent) {
  486. bitangent = Cartesian2.Cartesian3.clone(normal, bitangent);
  487. var next = Cartesian2.Cartesian3.fromArray(
  488. positions,
  489. (i + 3) % length,
  490. scratchCartesian4
  491. );
  492. Cartesian2.Cartesian3.subtract(next, position, next);
  493. var bottom = Cartesian2.Cartesian3.subtract(
  494. extrudedPosition,
  495. position,
  496. scratchCartesian3
  497. );
  498. normal = Cartesian2.Cartesian3.normalize(
  499. Cartesian2.Cartesian3.cross(bottom, next, normal),
  500. normal
  501. );
  502. if (vertexFormat.normal) {
  503. normals[i] = normal.x;
  504. normals[i1] = normal.y;
  505. normals[i2] = normal.z;
  506. normals[i + length] = normal.x;
  507. normals[i1 + length] = normal.y;
  508. normals[i2 + length] = normal.z;
  509. }
  510. if (vertexFormat.tangent) {
  511. tangent = Cartesian2.Cartesian3.normalize(
  512. Cartesian2.Cartesian3.cross(bitangent, normal, tangent),
  513. tangent
  514. );
  515. tangents[i] = tangent.x;
  516. tangents[i1] = tangent.y;
  517. tangents[i2] = tangent.z;
  518. tangents[i + length] = tangent.x;
  519. tangents[i + 1 + length] = tangent.y;
  520. tangents[i + 2 + length] = tangent.z;
  521. }
  522. if (vertexFormat.bitangent) {
  523. bitangents[i] = bitangent.x;
  524. bitangents[i1] = bitangent.y;
  525. bitangents[i2] = bitangent.z;
  526. bitangents[i + length] = bitangent.x;
  527. bitangents[i1 + length] = bitangent.y;
  528. bitangents[i2 + length] = bitangent.z;
  529. }
  530. }
  531. }
  532. if (vertexFormat.st) {
  533. length = textureCoordinates.length;
  534. for (var k = 0; k < length; k += 2) {
  535. textureCoordinates[k] =
  536. (textureCoordinates[k] - minTexCoord.x) /
  537. (maxTexCoord.x - minTexCoord.x);
  538. textureCoordinates[k + 1] =
  539. (textureCoordinates[k + 1] - minTexCoord.y) /
  540. (maxTexCoord.y - minTexCoord.y);
  541. }
  542. }
  543. var attributes = new GeometryAttributes.GeometryAttributes();
  544. if (vertexFormat.position) {
  545. attributes.position = new GeometryAttribute.GeometryAttribute({
  546. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  547. componentsPerAttribute: 3,
  548. values: finalPositions,
  549. });
  550. }
  551. if (vertexFormat.st) {
  552. attributes.st = new GeometryAttribute.GeometryAttribute({
  553. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  554. componentsPerAttribute: 2,
  555. values: textureCoordinates,
  556. });
  557. }
  558. if (vertexFormat.normal) {
  559. attributes.normal = new GeometryAttribute.GeometryAttribute({
  560. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  561. componentsPerAttribute: 3,
  562. values: normals,
  563. });
  564. }
  565. if (vertexFormat.tangent) {
  566. attributes.tangent = new GeometryAttribute.GeometryAttribute({
  567. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  568. componentsPerAttribute: 3,
  569. values: tangents,
  570. });
  571. }
  572. if (vertexFormat.bitangent) {
  573. attributes.bitangent = new GeometryAttribute.GeometryAttribute({
  574. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  575. componentsPerAttribute: 3,
  576. values: bitangents,
  577. });
  578. }
  579. if (shadowVolume) {
  580. attributes.extrudeDirection = new GeometryAttribute.GeometryAttribute({
  581. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  582. componentsPerAttribute: 3,
  583. values: extrudeNormals,
  584. });
  585. }
  586. if (when.defined(options.offsetAttribute)) {
  587. var offsetAttribute = new Uint8Array(size);
  588. if (options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  589. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, 1, 0, size / 2);
  590. } else {
  591. var offsetValue =
  592. options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  593. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, offsetValue);
  594. }
  595. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  596. componentDatatype: ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  597. componentsPerAttribute: 1,
  598. values: offsetAttribute,
  599. });
  600. }
  601. return attributes;
  602. }
  603. function computeWallIndices(positions) {
  604. var length = positions.length / 3;
  605. var indices = IndexDatatype.IndexDatatype.createTypedArray(length, length * 6);
  606. var index = 0;
  607. for (var i = 0; i < length; i++) {
  608. var UL = i;
  609. var LL = i + length;
  610. var UR = (UL + 1) % length;
  611. var LR = UR + length;
  612. indices[index++] = UL;
  613. indices[index++] = LL;
  614. indices[index++] = UR;
  615. indices[index++] = UR;
  616. indices[index++] = LL;
  617. indices[index++] = LR;
  618. }
  619. return indices;
  620. }
  621. var topBoundingSphere = new Transforms.BoundingSphere();
  622. var bottomBoundingSphere = new Transforms.BoundingSphere();
  623. function computeExtrudedEllipse(options) {
  624. var center = options.center;
  625. var ellipsoid = options.ellipsoid;
  626. var semiMajorAxis = options.semiMajorAxis;
  627. var scaledNormal = Cartesian2.Cartesian3.multiplyByScalar(
  628. ellipsoid.geodeticSurfaceNormal(center, scratchCartesian1),
  629. options.height,
  630. scratchCartesian1
  631. );
  632. topBoundingSphere.center = Cartesian2.Cartesian3.add(
  633. center,
  634. scaledNormal,
  635. topBoundingSphere.center
  636. );
  637. topBoundingSphere.radius = semiMajorAxis;
  638. scaledNormal = Cartesian2.Cartesian3.multiplyByScalar(
  639. ellipsoid.geodeticSurfaceNormal(center, scaledNormal),
  640. options.extrudedHeight,
  641. scaledNormal
  642. );
  643. bottomBoundingSphere.center = Cartesian2.Cartesian3.add(
  644. center,
  645. scaledNormal,
  646. bottomBoundingSphere.center
  647. );
  648. bottomBoundingSphere.radius = semiMajorAxis;
  649. var cep = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(options, true, true);
  650. var positions = cep.positions;
  651. var numPts = cep.numPts;
  652. var outerPositions = cep.outerPositions;
  653. var boundingSphere = Transforms.BoundingSphere.union(
  654. topBoundingSphere,
  655. bottomBoundingSphere
  656. );
  657. var topBottomAttributes = computeTopBottomAttributes(
  658. positions,
  659. options,
  660. true
  661. );
  662. var indices = topIndices(numPts);
  663. var length = indices.length;
  664. indices.length = length * 2;
  665. var posLength = positions.length / 3;
  666. for (var i = 0; i < length; i += 3) {
  667. indices[i + length] = indices[i + 2] + posLength;
  668. indices[i + 1 + length] = indices[i + 1] + posLength;
  669. indices[i + 2 + length] = indices[i] + posLength;
  670. }
  671. var topBottomIndices = IndexDatatype.IndexDatatype.createTypedArray(
  672. (posLength * 2) / 3,
  673. indices
  674. );
  675. var topBottomGeo = new GeometryAttribute.Geometry({
  676. attributes: topBottomAttributes,
  677. indices: topBottomIndices,
  678. primitiveType: GeometryAttribute.PrimitiveType.TRIANGLES,
  679. });
  680. var wallAttributes = computeWallAttributes(outerPositions, options);
  681. indices = computeWallIndices(outerPositions);
  682. var wallIndices = IndexDatatype.IndexDatatype.createTypedArray(
  683. (outerPositions.length * 2) / 3,
  684. indices
  685. );
  686. var wallGeo = new GeometryAttribute.Geometry({
  687. attributes: wallAttributes,
  688. indices: wallIndices,
  689. primitiveType: GeometryAttribute.PrimitiveType.TRIANGLES,
  690. });
  691. var geo = GeometryPipeline.GeometryPipeline.combineInstances([
  692. new GeometryInstance.GeometryInstance({
  693. geometry: topBottomGeo,
  694. }),
  695. new GeometryInstance.GeometryInstance({
  696. geometry: wallGeo,
  697. }),
  698. ]);
  699. return {
  700. boundingSphere: boundingSphere,
  701. attributes: geo[0].attributes,
  702. indices: geo[0].indices,
  703. };
  704. }
  705. function computeRectangle(
  706. center,
  707. semiMajorAxis,
  708. semiMinorAxis,
  709. rotation,
  710. granularity,
  711. ellipsoid,
  712. result
  713. ) {
  714. var cep = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(
  715. {
  716. center: center,
  717. semiMajorAxis: semiMajorAxis,
  718. semiMinorAxis: semiMinorAxis,
  719. rotation: rotation,
  720. granularity: granularity,
  721. },
  722. false,
  723. true
  724. );
  725. var positionsFlat = cep.outerPositions;
  726. var positionsCount = positionsFlat.length / 3;
  727. var positions = new Array(positionsCount);
  728. for (var i = 0; i < positionsCount; ++i) {
  729. positions[i] = Cartesian2.Cartesian3.fromArray(positionsFlat, i * 3);
  730. }
  731. var rectangle = Cartesian2.Rectangle.fromCartesianArray(positions, ellipsoid, result);
  732. // Rectangle width goes beyond 180 degrees when the ellipse crosses a pole.
  733. // When this happens, make the rectangle into a "circle" around the pole
  734. if (rectangle.width > _Math.CesiumMath.PI) {
  735. rectangle.north =
  736. rectangle.north > 0.0
  737. ? _Math.CesiumMath.PI_OVER_TWO - _Math.CesiumMath.EPSILON7
  738. : rectangle.north;
  739. rectangle.south =
  740. rectangle.south < 0.0
  741. ? _Math.CesiumMath.EPSILON7 - _Math.CesiumMath.PI_OVER_TWO
  742. : rectangle.south;
  743. rectangle.east = _Math.CesiumMath.PI;
  744. rectangle.west = -_Math.CesiumMath.PI;
  745. }
  746. return rectangle;
  747. }
  748. /**
  749. * A description of an ellipse on an ellipsoid. Ellipse geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}.
  750. *
  751. * @alias EllipseGeometry
  752. * @constructor
  753. *
  754. * @param {Object} options Object with the following properties:
  755. * @param {Cartesian3} options.center The ellipse's center point in the fixed frame.
  756. * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters.
  757. * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters.
  758. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on.
  759. * @param {Number} [options.height=0.0] The distance in meters between the ellipse and the ellipsoid surface.
  760. * @param {Number} [options.extrudedHeight] The distance in meters between the ellipse's extruded face and the ellipsoid surface.
  761. * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north.
  762. * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates counter-clockwise from north.
  763. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians.
  764. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  765. *
  766. * @exception {DeveloperError} semiMajorAxis and semiMinorAxis must be greater than zero.
  767. * @exception {DeveloperError} semiMajorAxis must be greater than or equal to the semiMinorAxis.
  768. * @exception {DeveloperError} granularity must be greater than zero.
  769. *
  770. *
  771. * @example
  772. * // Create an ellipse.
  773. * var ellipse = new Cesium.EllipseGeometry({
  774. * center : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
  775. * semiMajorAxis : 500000.0,
  776. * semiMinorAxis : 300000.0,
  777. * rotation : Cesium.Math.toRadians(60.0)
  778. * });
  779. * var geometry = Cesium.EllipseGeometry.createGeometry(ellipse);
  780. *
  781. * @see EllipseGeometry.createGeometry
  782. */
  783. function EllipseGeometry(options) {
  784. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  785. var center = options.center;
  786. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  787. var semiMajorAxis = options.semiMajorAxis;
  788. var semiMinorAxis = options.semiMinorAxis;
  789. var granularity = when.defaultValue(
  790. options.granularity,
  791. _Math.CesiumMath.RADIANS_PER_DEGREE
  792. );
  793. var vertexFormat = when.defaultValue(options.vertexFormat, VertexFormat.VertexFormat.DEFAULT);
  794. //>>includeStart('debug', pragmas.debug);
  795. Check.Check.defined("options.center", center);
  796. Check.Check.typeOf.number("options.semiMajorAxis", semiMajorAxis);
  797. Check.Check.typeOf.number("options.semiMinorAxis", semiMinorAxis);
  798. if (semiMajorAxis < semiMinorAxis) {
  799. throw new Check.DeveloperError(
  800. "semiMajorAxis must be greater than or equal to the semiMinorAxis."
  801. );
  802. }
  803. if (granularity <= 0.0) {
  804. throw new Check.DeveloperError("granularity must be greater than zero.");
  805. }
  806. //>>includeEnd('debug');
  807. var height = when.defaultValue(options.height, 0.0);
  808. var extrudedHeight = when.defaultValue(options.extrudedHeight, height);
  809. this._center = Cartesian2.Cartesian3.clone(center);
  810. this._semiMajorAxis = semiMajorAxis;
  811. this._semiMinorAxis = semiMinorAxis;
  812. this._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid);
  813. this._rotation = when.defaultValue(options.rotation, 0.0);
  814. this._stRotation = when.defaultValue(options.stRotation, 0.0);
  815. this._height = Math.max(extrudedHeight, height);
  816. this._granularity = granularity;
  817. this._vertexFormat = VertexFormat.VertexFormat.clone(vertexFormat);
  818. this._extrudedHeight = Math.min(extrudedHeight, height);
  819. this._shadowVolume = when.defaultValue(options.shadowVolume, false);
  820. this._workerName = "createEllipseGeometry";
  821. this._offsetAttribute = options.offsetAttribute;
  822. this._rectangle = undefined;
  823. this._textureCoordinateRotationPoints = undefined;
  824. }
  825. /**
  826. * The number of elements used to pack the object into an array.
  827. * @type {Number}
  828. */
  829. EllipseGeometry.packedLength =
  830. Cartesian2.Cartesian3.packedLength +
  831. Cartesian2.Ellipsoid.packedLength +
  832. VertexFormat.VertexFormat.packedLength +
  833. 9;
  834. /**
  835. * Stores the provided instance into the provided array.
  836. *
  837. * @param {EllipseGeometry} value The value to pack.
  838. * @param {Number[]} array The array to pack into.
  839. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  840. *
  841. * @returns {Number[]} The array that was packed into
  842. */
  843. EllipseGeometry.pack = function (value, array, startingIndex) {
  844. //>>includeStart('debug', pragmas.debug);
  845. Check.Check.defined("value", value);
  846. Check.Check.defined("array", array);
  847. //>>includeEnd('debug');
  848. startingIndex = when.defaultValue(startingIndex, 0);
  849. Cartesian2.Cartesian3.pack(value._center, array, startingIndex);
  850. startingIndex += Cartesian2.Cartesian3.packedLength;
  851. Cartesian2.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  852. startingIndex += Cartesian2.Ellipsoid.packedLength;
  853. VertexFormat.VertexFormat.pack(value._vertexFormat, array, startingIndex);
  854. startingIndex += VertexFormat.VertexFormat.packedLength;
  855. array[startingIndex++] = value._semiMajorAxis;
  856. array[startingIndex++] = value._semiMinorAxis;
  857. array[startingIndex++] = value._rotation;
  858. array[startingIndex++] = value._stRotation;
  859. array[startingIndex++] = value._height;
  860. array[startingIndex++] = value._granularity;
  861. array[startingIndex++] = value._extrudedHeight;
  862. array[startingIndex++] = value._shadowVolume ? 1.0 : 0.0;
  863. array[startingIndex] = when.defaultValue(value._offsetAttribute, -1);
  864. return array;
  865. };
  866. var scratchCenter = new Cartesian2.Cartesian3();
  867. var scratchEllipsoid = new Cartesian2.Ellipsoid();
  868. var scratchVertexFormat = new VertexFormat.VertexFormat();
  869. var scratchOptions = {
  870. center: scratchCenter,
  871. ellipsoid: scratchEllipsoid,
  872. vertexFormat: scratchVertexFormat,
  873. semiMajorAxis: undefined,
  874. semiMinorAxis: undefined,
  875. rotation: undefined,
  876. stRotation: undefined,
  877. height: undefined,
  878. granularity: undefined,
  879. extrudedHeight: undefined,
  880. shadowVolume: undefined,
  881. offsetAttribute: undefined,
  882. };
  883. /**
  884. * Retrieves an instance from a packed array.
  885. *
  886. * @param {Number[]} array The packed array.
  887. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  888. * @param {EllipseGeometry} [result] The object into which to store the result.
  889. * @returns {EllipseGeometry} The modified result parameter or a new EllipseGeometry instance if one was not provided.
  890. */
  891. EllipseGeometry.unpack = function (array, startingIndex, result) {
  892. //>>includeStart('debug', pragmas.debug);
  893. Check.Check.defined("array", array);
  894. //>>includeEnd('debug');
  895. startingIndex = when.defaultValue(startingIndex, 0);
  896. var center = Cartesian2.Cartesian3.unpack(array, startingIndex, scratchCenter);
  897. startingIndex += Cartesian2.Cartesian3.packedLength;
  898. var ellipsoid = Cartesian2.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  899. startingIndex += Cartesian2.Ellipsoid.packedLength;
  900. var vertexFormat = VertexFormat.VertexFormat.unpack(
  901. array,
  902. startingIndex,
  903. scratchVertexFormat
  904. );
  905. startingIndex += VertexFormat.VertexFormat.packedLength;
  906. var semiMajorAxis = array[startingIndex++];
  907. var semiMinorAxis = array[startingIndex++];
  908. var rotation = array[startingIndex++];
  909. var stRotation = array[startingIndex++];
  910. var height = array[startingIndex++];
  911. var granularity = array[startingIndex++];
  912. var extrudedHeight = array[startingIndex++];
  913. var shadowVolume = array[startingIndex++] === 1.0;
  914. var offsetAttribute = array[startingIndex];
  915. if (!when.defined(result)) {
  916. scratchOptions.height = height;
  917. scratchOptions.extrudedHeight = extrudedHeight;
  918. scratchOptions.granularity = granularity;
  919. scratchOptions.stRotation = stRotation;
  920. scratchOptions.rotation = rotation;
  921. scratchOptions.semiMajorAxis = semiMajorAxis;
  922. scratchOptions.semiMinorAxis = semiMinorAxis;
  923. scratchOptions.shadowVolume = shadowVolume;
  924. scratchOptions.offsetAttribute =
  925. offsetAttribute === -1 ? undefined : offsetAttribute;
  926. return new EllipseGeometry(scratchOptions);
  927. }
  928. result._center = Cartesian2.Cartesian3.clone(center, result._center);
  929. result._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  930. result._vertexFormat = VertexFormat.VertexFormat.clone(vertexFormat, result._vertexFormat);
  931. result._semiMajorAxis = semiMajorAxis;
  932. result._semiMinorAxis = semiMinorAxis;
  933. result._rotation = rotation;
  934. result._stRotation = stRotation;
  935. result._height = height;
  936. result._granularity = granularity;
  937. result._extrudedHeight = extrudedHeight;
  938. result._shadowVolume = shadowVolume;
  939. result._offsetAttribute =
  940. offsetAttribute === -1 ? undefined : offsetAttribute;
  941. return result;
  942. };
  943. /**
  944. * Computes the bounding rectangle based on the provided options
  945. *
  946. * @param {Object} options Object with the following properties:
  947. * @param {Cartesian3} options.center The ellipse's center point in the fixed frame.
  948. * @param {Number} options.semiMajorAxis The length of the ellipse's semi-major axis in meters.
  949. * @param {Number} options.semiMinorAxis The length of the ellipse's semi-minor axis in meters.
  950. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid the ellipse will be on.
  951. * @param {Number} [options.rotation=0.0] The angle of rotation counter-clockwise from north.
  952. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The angular distance between points on the ellipse in radians.
  953. * @param {Rectangle} [result] An object in which to store the result
  954. *
  955. * @returns {Rectangle} The result rectangle
  956. */
  957. EllipseGeometry.computeRectangle = function (options, result) {
  958. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  959. var center = options.center;
  960. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  961. var semiMajorAxis = options.semiMajorAxis;
  962. var semiMinorAxis = options.semiMinorAxis;
  963. var granularity = when.defaultValue(
  964. options.granularity,
  965. _Math.CesiumMath.RADIANS_PER_DEGREE
  966. );
  967. var rotation = when.defaultValue(options.rotation, 0.0);
  968. //>>includeStart('debug', pragmas.debug);
  969. Check.Check.defined("options.center", center);
  970. Check.Check.typeOf.number("options.semiMajorAxis", semiMajorAxis);
  971. Check.Check.typeOf.number("options.semiMinorAxis", semiMinorAxis);
  972. if (semiMajorAxis < semiMinorAxis) {
  973. throw new Check.DeveloperError(
  974. "semiMajorAxis must be greater than or equal to the semiMinorAxis."
  975. );
  976. }
  977. if (granularity <= 0.0) {
  978. throw new Check.DeveloperError("granularity must be greater than zero.");
  979. }
  980. //>>includeEnd('debug');
  981. return computeRectangle(
  982. center,
  983. semiMajorAxis,
  984. semiMinorAxis,
  985. rotation,
  986. granularity,
  987. ellipsoid,
  988. result
  989. );
  990. };
  991. /**
  992. * Computes the geometric representation of a ellipse on an ellipsoid, including its vertices, indices, and a bounding sphere.
  993. *
  994. * @param {EllipseGeometry} ellipseGeometry A description of the ellipse.
  995. * @returns {Geometry|undefined} The computed vertices and indices.
  996. */
  997. EllipseGeometry.createGeometry = function (ellipseGeometry) {
  998. if (
  999. ellipseGeometry._semiMajorAxis <= 0.0 ||
  1000. ellipseGeometry._semiMinorAxis <= 0.0
  1001. ) {
  1002. return;
  1003. }
  1004. var height = ellipseGeometry._height;
  1005. var extrudedHeight = ellipseGeometry._extrudedHeight;
  1006. var extrude = !_Math.CesiumMath.equalsEpsilon(
  1007. height,
  1008. extrudedHeight,
  1009. 0,
  1010. _Math.CesiumMath.EPSILON2
  1011. );
  1012. ellipseGeometry._center = ellipseGeometry._ellipsoid.scaleToGeodeticSurface(
  1013. ellipseGeometry._center,
  1014. ellipseGeometry._center
  1015. );
  1016. var options = {
  1017. center: ellipseGeometry._center,
  1018. semiMajorAxis: ellipseGeometry._semiMajorAxis,
  1019. semiMinorAxis: ellipseGeometry._semiMinorAxis,
  1020. ellipsoid: ellipseGeometry._ellipsoid,
  1021. rotation: ellipseGeometry._rotation,
  1022. height: height,
  1023. granularity: ellipseGeometry._granularity,
  1024. vertexFormat: ellipseGeometry._vertexFormat,
  1025. stRotation: ellipseGeometry._stRotation,
  1026. };
  1027. var geometry;
  1028. if (extrude) {
  1029. options.extrudedHeight = extrudedHeight;
  1030. options.shadowVolume = ellipseGeometry._shadowVolume;
  1031. options.offsetAttribute = ellipseGeometry._offsetAttribute;
  1032. geometry = computeExtrudedEllipse(options);
  1033. } else {
  1034. geometry = computeEllipse(options);
  1035. if (when.defined(ellipseGeometry._offsetAttribute)) {
  1036. var length = geometry.attributes.position.values.length;
  1037. var applyOffset = new Uint8Array(length / 3);
  1038. var offsetValue =
  1039. ellipseGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE
  1040. ? 0
  1041. : 1;
  1042. GeometryOffsetAttribute.arrayFill(applyOffset, offsetValue);
  1043. geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  1044. componentDatatype: ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  1045. componentsPerAttribute: 1,
  1046. values: applyOffset,
  1047. });
  1048. }
  1049. }
  1050. return new GeometryAttribute.Geometry({
  1051. attributes: geometry.attributes,
  1052. indices: geometry.indices,
  1053. primitiveType: GeometryAttribute.PrimitiveType.TRIANGLES,
  1054. boundingSphere: geometry.boundingSphere,
  1055. offsetAttribute: ellipseGeometry._offsetAttribute,
  1056. });
  1057. };
  1058. /**
  1059. * @private
  1060. */
  1061. EllipseGeometry.createShadowVolume = function (
  1062. ellipseGeometry,
  1063. minHeightFunc,
  1064. maxHeightFunc
  1065. ) {
  1066. var granularity = ellipseGeometry._granularity;
  1067. var ellipsoid = ellipseGeometry._ellipsoid;
  1068. var minHeight = minHeightFunc(granularity, ellipsoid);
  1069. var maxHeight = maxHeightFunc(granularity, ellipsoid);
  1070. return new EllipseGeometry({
  1071. center: ellipseGeometry._center,
  1072. semiMajorAxis: ellipseGeometry._semiMajorAxis,
  1073. semiMinorAxis: ellipseGeometry._semiMinorAxis,
  1074. ellipsoid: ellipsoid,
  1075. rotation: ellipseGeometry._rotation,
  1076. stRotation: ellipseGeometry._stRotation,
  1077. granularity: granularity,
  1078. extrudedHeight: minHeight,
  1079. height: maxHeight,
  1080. vertexFormat: VertexFormat.VertexFormat.POSITION_ONLY,
  1081. shadowVolume: true,
  1082. });
  1083. };
  1084. function textureCoordinateRotationPoints(ellipseGeometry) {
  1085. var stRotation = -ellipseGeometry._stRotation;
  1086. if (stRotation === 0.0) {
  1087. return [0, 0, 0, 1, 1, 0];
  1088. }
  1089. var cep = EllipseGeometryLibrary.EllipseGeometryLibrary.computeEllipsePositions(
  1090. {
  1091. center: ellipseGeometry._center,
  1092. semiMajorAxis: ellipseGeometry._semiMajorAxis,
  1093. semiMinorAxis: ellipseGeometry._semiMinorAxis,
  1094. rotation: ellipseGeometry._rotation,
  1095. granularity: ellipseGeometry._granularity,
  1096. },
  1097. false,
  1098. true
  1099. );
  1100. var positionsFlat = cep.outerPositions;
  1101. var positionsCount = positionsFlat.length / 3;
  1102. var positions = new Array(positionsCount);
  1103. for (var i = 0; i < positionsCount; ++i) {
  1104. positions[i] = Cartesian2.Cartesian3.fromArray(positionsFlat, i * 3);
  1105. }
  1106. var ellipsoid = ellipseGeometry._ellipsoid;
  1107. var boundingRectangle = ellipseGeometry.rectangle;
  1108. return GeometryAttribute.Geometry._textureCoordinateRotationPoints(
  1109. positions,
  1110. stRotation,
  1111. ellipsoid,
  1112. boundingRectangle
  1113. );
  1114. }
  1115. Object.defineProperties(EllipseGeometry.prototype, {
  1116. /**
  1117. * @private
  1118. */
  1119. rectangle: {
  1120. get: function () {
  1121. if (!when.defined(this._rectangle)) {
  1122. this._rectangle = computeRectangle(
  1123. this._center,
  1124. this._semiMajorAxis,
  1125. this._semiMinorAxis,
  1126. this._rotation,
  1127. this._granularity,
  1128. this._ellipsoid
  1129. );
  1130. }
  1131. return this._rectangle;
  1132. },
  1133. },
  1134. /**
  1135. * For remapping texture coordinates when rendering EllipseGeometries as GroundPrimitives.
  1136. * @private
  1137. */
  1138. textureCoordinateRotationPoints: {
  1139. get: function () {
  1140. if (!when.defined(this._textureCoordinateRotationPoints)) {
  1141. this._textureCoordinateRotationPoints = textureCoordinateRotationPoints(
  1142. this
  1143. );
  1144. }
  1145. return this._textureCoordinateRotationPoints;
  1146. },
  1147. },
  1148. });
  1149. exports.EllipseGeometry = EllipseGeometry;
  1150. });