createPolygonGeometry.js 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079
  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(['./when-8d13db60', './Check-70bec281', './Math-61ede240', './Cartographic-fe4be337', './Cartesian2-85064f09', './BoundingSphere-775c5788', './Cartesian4-5af5bb24', './RuntimeError-ba10bc3e', './WebGLConstants-4c11ee5f', './ComponentDatatype-5862616f', './GeometryAttribute-91704ebb', './PrimitiveType-97893bc7', './FeatureDetection-7bd32c34', './Transforms-b2e71640', './buildModuleUrl-14bfe498', './GeometryAttributes-aacecde6', './AttributeCompression-84a90a13', './GeometryPipeline-f95a0a6f', './EncodedCartesian3-a569cba8', './IndexDatatype-9435b55f', './IntersectionTests-397d9494', './Plane-8390418f', './GeometryOffsetAttribute-ca302482', './VertexFormat-fe4db402', './GeometryInstance-93a01b5d', './arrayRemoveDuplicates-f0b089b1', './BoundingRectangle-dc808c42', './EllipsoidTangentPlane-a815c96f', './ArcType-66bc286a', './EllipsoidRhumbLine-f161e674', './earcut-2.2.1-b404d9e6', './PolygonPipeline-6a35d737', './PolygonGeometryLibrary-073be5ba', './EllipsoidGeodesic-84507801'], function (when, Check, _Math, Cartographic, Cartesian2, BoundingSphere, Cartesian4, RuntimeError, WebGLConstants, ComponentDatatype, GeometryAttribute, PrimitiveType, FeatureDetection, Transforms, buildModuleUrl, GeometryAttributes, AttributeCompression, GeometryPipeline, EncodedCartesian3, IndexDatatype, IntersectionTests, Plane, GeometryOffsetAttribute, VertexFormat, GeometryInstance, arrayRemoveDuplicates, BoundingRectangle, EllipsoidTangentPlane, ArcType, EllipsoidRhumbLine, earcut2_2_1, PolygonPipeline, PolygonGeometryLibrary, EllipsoidGeodesic) { 'use strict';
  24. var scratchCarto1 = new Cartographic.Cartographic();
  25. var scratchCarto2 = new Cartographic.Cartographic();
  26. function adjustPosHeightsForNormal(position, p1, p2, ellipsoid) {
  27. var carto1 = ellipsoid.cartesianToCartographic(position, scratchCarto1);
  28. var height = carto1.height;
  29. var p1Carto = ellipsoid.cartesianToCartographic(p1, scratchCarto2);
  30. p1Carto.height = height;
  31. ellipsoid.cartographicToCartesian(p1Carto, p1);
  32. var p2Carto = ellipsoid.cartesianToCartographic(p2, scratchCarto2);
  33. p2Carto.height = height - 100;
  34. ellipsoid.cartographicToCartesian(p2Carto, p2);
  35. }
  36. var scratchBoundingRectangle = new BoundingRectangle.BoundingRectangle();
  37. var scratchPosition = new Cartographic.Cartesian3();
  38. var scratchNormal = new Cartographic.Cartesian3();
  39. var scratchTangent = new Cartographic.Cartesian3();
  40. var scratchBitangent = new Cartographic.Cartesian3();
  41. var p1Scratch = new Cartographic.Cartesian3();
  42. var p2Scratch = new Cartographic.Cartesian3();
  43. var scratchPerPosNormal = new Cartographic.Cartesian3();
  44. var scratchPerPosTangent = new Cartographic.Cartesian3();
  45. var scratchPerPosBitangent = new Cartographic.Cartesian3();
  46. var appendTextureCoordinatesOrigin = new Cartesian2.Cartesian2();
  47. var appendTextureCoordinatesCartesian2 = new Cartesian2.Cartesian2();
  48. var appendTextureCoordinatesCartesian3 = new Cartographic.Cartesian3();
  49. var appendTextureCoordinatesQuaternion = new Transforms.Quaternion();
  50. var appendTextureCoordinatesMatrix3 = new BoundingSphere.Matrix3();
  51. var tangentMatrixScratch = new BoundingSphere.Matrix3();
  52. function computeAttributes(options) {
  53. var vertexFormat = options.vertexFormat;
  54. var geometry = options.geometry;
  55. var shadowVolume = options.shadowVolume;
  56. var flatPositions = geometry.attributes.position.values;
  57. var length = flatPositions.length;
  58. var wall = options.wall;
  59. var top = options.top || wall;
  60. var bottom = options.bottom || wall;
  61. if (vertexFormat.st || vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) {
  62. // PERFORMANCE_IDEA: Compute before subdivision, then just interpolate during subdivision.
  63. // PERFORMANCE_IDEA: Compute with createGeometryFromPositions() for fast path when there's no holes.
  64. var boundingRectangle = options.boundingRectangle;
  65. var tangentPlane = options.tangentPlane;
  66. var ellipsoid = options.ellipsoid;
  67. var stRotation = options.stRotation;
  68. var perPositionHeight = options.perPositionHeight;
  69. var origin = appendTextureCoordinatesOrigin;
  70. origin.x = boundingRectangle.x;
  71. origin.y = boundingRectangle.y;
  72. var textureCoordinates = vertexFormat.st ? new Float32Array(2 * (length / 3)) : undefined;
  73. var normals;
  74. if (vertexFormat.normal) {
  75. if (perPositionHeight && top && !wall) {
  76. normals = geometry.attributes.normal.values;
  77. } else {
  78. normals = new Float32Array(length);
  79. }
  80. }
  81. var tangents = vertexFormat.tangent ? new Float32Array(length) : undefined;
  82. var bitangents = vertexFormat.bitangent ? new Float32Array(length) : undefined;
  83. var extrudeNormals = shadowVolume ? new Float32Array(length) : undefined;
  84. var textureCoordIndex = 0;
  85. var attrIndex = 0;
  86. var normal = scratchNormal;
  87. var tangent = scratchTangent;
  88. var bitangent = scratchBitangent;
  89. var recomputeNormal = true;
  90. var textureMatrix = appendTextureCoordinatesMatrix3;
  91. var tangentRotationMatrix = tangentMatrixScratch;
  92. if (stRotation !== 0.0) {
  93. var rotation = Transforms.Quaternion.fromAxisAngle(tangentPlane._plane.normal, stRotation, appendTextureCoordinatesQuaternion);
  94. textureMatrix = BoundingSphere.Matrix3.fromQuaternion(rotation, textureMatrix);
  95. rotation = Transforms.Quaternion.fromAxisAngle(tangentPlane._plane.normal, -stRotation, appendTextureCoordinatesQuaternion);
  96. tangentRotationMatrix = BoundingSphere.Matrix3.fromQuaternion(rotation, tangentRotationMatrix);
  97. } else {
  98. textureMatrix = BoundingSphere.Matrix3.clone(BoundingSphere.Matrix3.IDENTITY, textureMatrix);
  99. tangentRotationMatrix = BoundingSphere.Matrix3.clone(BoundingSphere.Matrix3.IDENTITY, tangentRotationMatrix);
  100. }
  101. var bottomOffset = 0;
  102. var bottomOffset2 = 0;
  103. if (top && bottom) {
  104. bottomOffset = length / 2;
  105. bottomOffset2 = length / 3;
  106. length /= 2;
  107. }
  108. for ( var i = 0; i < length; i += 3) {
  109. var position = Cartographic.Cartesian3.fromArray(flatPositions, i, appendTextureCoordinatesCartesian3);
  110. if (vertexFormat.st) {
  111. var p = BoundingSphere.Matrix3.multiplyByVector(textureMatrix, position, scratchPosition);
  112. p = ellipsoid.scaleToGeodeticSurface(p,p);
  113. var st = tangentPlane.projectPointOntoPlane(p, appendTextureCoordinatesCartesian2);
  114. Cartesian2.Cartesian2.subtract(st, origin, st);
  115. var stx = _Math.CesiumMath.clamp(st.x / boundingRectangle.width, 0, 1);
  116. var sty = _Math.CesiumMath.clamp(st.y / boundingRectangle.height, 0, 1);
  117. if (bottom) {
  118. textureCoordinates[textureCoordIndex + bottomOffset2] = stx;
  119. textureCoordinates[textureCoordIndex + 1 + bottomOffset2] = sty;
  120. }
  121. if (top) {
  122. textureCoordinates[textureCoordIndex] = stx;
  123. textureCoordinates[textureCoordIndex + 1] = sty;
  124. }
  125. textureCoordIndex += 2;
  126. }
  127. if (vertexFormat.normal || vertexFormat.tangent || vertexFormat.bitangent || shadowVolume) {
  128. var attrIndex1 = attrIndex + 1;
  129. var attrIndex2 = attrIndex + 2;
  130. if (wall) {
  131. if (i + 3 < length) {
  132. var p1 = Cartographic.Cartesian3.fromArray(flatPositions, i + 3, p1Scratch);
  133. if (recomputeNormal) {
  134. var p2 = Cartographic.Cartesian3.fromArray(flatPositions, i + length, p2Scratch);
  135. if (perPositionHeight) {
  136. adjustPosHeightsForNormal(position, p1, p2, ellipsoid);
  137. }
  138. Cartographic.Cartesian3.subtract(p1, position, p1);
  139. Cartographic.Cartesian3.subtract(p2, position, p2);
  140. normal = Cartographic.Cartesian3.normalize(Cartographic.Cartesian3.cross(p2, p1, normal), normal);
  141. recomputeNormal = false;
  142. }
  143. if (Cartographic.Cartesian3.equalsEpsilon(p1, position, _Math.CesiumMath.EPSILON10)) { // if we've reached a corner
  144. recomputeNormal = true;
  145. }
  146. }
  147. if (vertexFormat.tangent || vertexFormat.bitangent) {
  148. bitangent = ellipsoid.geodeticSurfaceNormal(position, bitangent);
  149. if (vertexFormat.tangent) {
  150. tangent = Cartographic.Cartesian3.normalize(Cartographic.Cartesian3.cross(bitangent, normal, tangent), tangent);
  151. }
  152. }
  153. } else {
  154. normal = ellipsoid.geodeticSurfaceNormal(position, normal);
  155. if (vertexFormat.tangent || vertexFormat.bitangent) {
  156. if (perPositionHeight) {
  157. scratchPerPosNormal = Cartographic.Cartesian3.fromArray(normals, attrIndex, scratchPerPosNormal);
  158. scratchPerPosTangent = Cartographic.Cartesian3.cross(Cartographic.Cartesian3.UNIT_Z, scratchPerPosNormal, scratchPerPosTangent);
  159. scratchPerPosTangent = Cartographic.Cartesian3.normalize(BoundingSphere.Matrix3.multiplyByVector(tangentRotationMatrix, scratchPerPosTangent, scratchPerPosTangent), scratchPerPosTangent);
  160. if (vertexFormat.bitangent) {
  161. scratchPerPosBitangent = Cartographic.Cartesian3.normalize(Cartographic.Cartesian3.cross(scratchPerPosNormal, scratchPerPosTangent, scratchPerPosBitangent), scratchPerPosBitangent);
  162. }
  163. }
  164. tangent = Cartographic.Cartesian3.cross(Cartographic.Cartesian3.UNIT_Z, normal, tangent);
  165. tangent = Cartographic.Cartesian3.normalize(BoundingSphere.Matrix3.multiplyByVector(tangentRotationMatrix, tangent, tangent), tangent);
  166. if (vertexFormat.bitangent) {
  167. bitangent = Cartographic.Cartesian3.normalize(Cartographic.Cartesian3.cross(normal, tangent, bitangent), bitangent);
  168. }
  169. }
  170. }
  171. if (vertexFormat.normal) {
  172. if (options.wall) {
  173. normals[attrIndex + bottomOffset] = normal.x;
  174. normals[attrIndex1 + bottomOffset] = normal.y;
  175. normals[attrIndex2 + bottomOffset] = normal.z;
  176. } else if (bottom){
  177. normals[attrIndex + bottomOffset] = -normal.x;
  178. normals[attrIndex1 + bottomOffset] = -normal.y;
  179. normals[attrIndex2 + bottomOffset] = -normal.z;
  180. }
  181. if ((top && !perPositionHeight) || wall) {
  182. normals[attrIndex] = normal.x;
  183. normals[attrIndex1] = normal.y;
  184. normals[attrIndex2] = normal.z;
  185. }
  186. }
  187. if (shadowVolume) {
  188. if (wall) {
  189. normal = ellipsoid.geodeticSurfaceNormal(position, normal);
  190. }
  191. extrudeNormals[attrIndex + bottomOffset] = -normal.x;
  192. extrudeNormals[attrIndex1 + bottomOffset] = -normal.y;
  193. extrudeNormals[attrIndex2 + bottomOffset] = -normal.z;
  194. }
  195. if (vertexFormat.tangent) {
  196. if (options.wall) {
  197. tangents[attrIndex + bottomOffset] = tangent.x;
  198. tangents[attrIndex1 + bottomOffset] = tangent.y;
  199. tangents[attrIndex2 + bottomOffset] = tangent.z;
  200. } else if (bottom) {
  201. tangents[attrIndex + bottomOffset] = -tangent.x;
  202. tangents[attrIndex1 + bottomOffset] = -tangent.y;
  203. tangents[attrIndex2 + bottomOffset] = -tangent.z;
  204. }
  205. if(top) {
  206. if (perPositionHeight) {
  207. tangents[attrIndex] = scratchPerPosTangent.x;
  208. tangents[attrIndex1] = scratchPerPosTangent.y;
  209. tangents[attrIndex2] = scratchPerPosTangent.z;
  210. } else {
  211. tangents[attrIndex] = tangent.x;
  212. tangents[attrIndex1] = tangent.y;
  213. tangents[attrIndex2] = tangent.z;
  214. }
  215. }
  216. }
  217. if (vertexFormat.bitangent) {
  218. if (bottom) {
  219. bitangents[attrIndex + bottomOffset] = bitangent.x;
  220. bitangents[attrIndex1 + bottomOffset] = bitangent.y;
  221. bitangents[attrIndex2 + bottomOffset] = bitangent.z;
  222. }
  223. if (top) {
  224. if (perPositionHeight) {
  225. bitangents[attrIndex] = scratchPerPosBitangent.x;
  226. bitangents[attrIndex1] = scratchPerPosBitangent.y;
  227. bitangents[attrIndex2] = scratchPerPosBitangent.z;
  228. } else {
  229. bitangents[attrIndex] = bitangent.x;
  230. bitangents[attrIndex1] = bitangent.y;
  231. bitangents[attrIndex2] = bitangent.z;
  232. }
  233. }
  234. }
  235. attrIndex += 3;
  236. }
  237. }
  238. if (vertexFormat.st) {
  239. geometry.attributes.st = new GeometryAttribute.GeometryAttribute({
  240. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  241. componentsPerAttribute : 2,
  242. values : textureCoordinates
  243. });
  244. }
  245. if (vertexFormat.normal) {
  246. geometry.attributes.normal = new GeometryAttribute.GeometryAttribute({
  247. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  248. componentsPerAttribute : 3,
  249. values : normals
  250. });
  251. }
  252. if (vertexFormat.tangent) {
  253. geometry.attributes.tangent = new GeometryAttribute.GeometryAttribute({
  254. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  255. componentsPerAttribute : 3,
  256. values : tangents
  257. });
  258. }
  259. if (vertexFormat.bitangent) {
  260. geometry.attributes.bitangent = new GeometryAttribute.GeometryAttribute({
  261. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  262. componentsPerAttribute : 3,
  263. values : bitangents
  264. });
  265. }
  266. if (shadowVolume) {
  267. geometry.attributes.extrudeDirection = new GeometryAttribute.GeometryAttribute({
  268. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  269. componentsPerAttribute : 3,
  270. values : extrudeNormals
  271. });
  272. }
  273. }
  274. if (options.extrude && when.defined(options.offsetAttribute)) {
  275. var size = flatPositions.length / 3;
  276. var offsetAttribute = new Uint8Array(size);
  277. if (options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  278. if ((top && bottom) || wall) {
  279. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, 1, 0, size / 2);
  280. } else if (top) {
  281. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, 1);
  282. }
  283. } else {
  284. var offsetValue = options.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  285. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, offsetValue);
  286. }
  287. geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  288. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  289. componentsPerAttribute : 1,
  290. values : offsetAttribute
  291. });
  292. }
  293. return geometry;
  294. }
  295. var startCartographicScratch = new Cartographic.Cartographic();
  296. var endCartographicScratch = new Cartographic.Cartographic();
  297. var idlCross = {
  298. west : 0.0,
  299. east : 0.0
  300. };
  301. var ellipsoidGeodesic = new EllipsoidGeodesic.EllipsoidGeodesic();
  302. function computeRectangle(positions, ellipsoid, arcType, granularity, result) {
  303. result = when.defaultValue(result, new Cartesian2.Rectangle());
  304. if (!when.defined(positions) || positions.length < 3) {
  305. result.west = 0.0;
  306. result.north = 0.0;
  307. result.south = 0.0;
  308. result.east = 0.0;
  309. return result;
  310. }
  311. if (arcType === ArcType.ArcType.RHUMB) {
  312. return Cartesian2.Rectangle.fromCartesianArray(positions, ellipsoid, result);
  313. }
  314. if (!ellipsoidGeodesic.ellipsoid.equals(ellipsoid)) {
  315. ellipsoidGeodesic = new EllipsoidGeodesic.EllipsoidGeodesic(undefined, undefined, ellipsoid);
  316. }
  317. result.west = Number.POSITIVE_INFINITY;
  318. result.east = Number.NEGATIVE_INFINITY;
  319. result.south = Number.POSITIVE_INFINITY;
  320. result.north = Number.NEGATIVE_INFINITY;
  321. idlCross.west = Number.POSITIVE_INFINITY;
  322. idlCross.east = Number.NEGATIVE_INFINITY;
  323. var inverseChordLength = 1.0 / _Math.CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
  324. var positionsLength = positions.length;
  325. var endCartographic = ellipsoid.cartesianToCartographic(positions[0], endCartographicScratch);
  326. var startCartographic = startCartographicScratch;
  327. var swap;
  328. for (var i = 1; i < positionsLength; i++) {
  329. swap = startCartographic;
  330. startCartographic = endCartographic;
  331. endCartographic = ellipsoid.cartesianToCartographic(positions[i], swap);
  332. ellipsoidGeodesic.setEndPoints(startCartographic, endCartographic);
  333. interpolateAndGrowRectangle(ellipsoidGeodesic, inverseChordLength, result, idlCross);
  334. }
  335. swap = startCartographic;
  336. startCartographic = endCartographic;
  337. endCartographic = ellipsoid.cartesianToCartographic(positions[0], swap);
  338. ellipsoidGeodesic.setEndPoints(startCartographic, endCartographic);
  339. interpolateAndGrowRectangle(ellipsoidGeodesic, inverseChordLength, result, idlCross);
  340. if (result.east - result.west > idlCross.west - idlCross.east) {
  341. result.east = idlCross.east;
  342. result.west = idlCross.west;
  343. }
  344. return result;
  345. }
  346. var interpolatedCartographicScratch = new Cartographic.Cartographic();
  347. function interpolateAndGrowRectangle(ellipsoidGeodesic, inverseChordLength, result, idlCross) {
  348. var segmentLength = ellipsoidGeodesic.surfaceDistance;
  349. var numPoints = Math.ceil(segmentLength * inverseChordLength);
  350. var subsegmentDistance = numPoints > 0 ? segmentLength / (numPoints - 1) : Number.POSITIVE_INFINITY;
  351. var interpolationDistance = 0.0;
  352. for (var i = 0; i < numPoints; i++) {
  353. var interpolatedCartographic = ellipsoidGeodesic.interpolateUsingSurfaceDistance(interpolationDistance, interpolatedCartographicScratch);
  354. interpolationDistance += subsegmentDistance;
  355. var longitude = interpolatedCartographic.longitude;
  356. var latitude = interpolatedCartographic.latitude;
  357. result.west = Math.min(result.west, longitude);
  358. result.east = Math.max(result.east, longitude);
  359. result.south = Math.min(result.south, latitude);
  360. result.north = Math.max(result.north, latitude);
  361. idlCross.west = longitude > 0.0 ? Math.min(longitude, idlCross.west) : idlCross.west;
  362. idlCross.east = longitude < 0.0 ? Math.max(longitude, idlCross.east) : idlCross.east;
  363. }
  364. }
  365. var createGeometryFromPositionsExtrudedPositions = [];
  366. function createGeometryFromPositionsExtruded(ellipsoid, polygon, granularity, hierarchy, perPositionHeight, closeTop, closeBottom, vertexFormat, arcType, extrudeOutering) {
  367. var geos = {
  368. walls : []
  369. };
  370. var i;
  371. if (closeTop || closeBottom) {
  372. var topGeo = PolygonGeometryLibrary.PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygon, granularity, perPositionHeight, vertexFormat, arcType);
  373. var edgePoints = topGeo.attributes.position.values;
  374. var indices = topGeo.indices;
  375. var numPositions;
  376. var newIndices;
  377. if (closeTop && closeBottom) {
  378. var topBottomPositions = edgePoints.concat(edgePoints);
  379. numPositions = topBottomPositions.length / 3;
  380. newIndices = IndexDatatype.IndexDatatype.createTypedArray(numPositions, indices.length * 2);
  381. newIndices.set(indices);
  382. var ilength = indices.length;
  383. var length = numPositions / 2;
  384. for (i = 0; i < ilength; i += 3) {
  385. var i0 = newIndices[i] + length;
  386. var i1 = newIndices[i + 1] + length;
  387. var i2 = newIndices[i + 2] + length;
  388. newIndices[i + ilength] = i2;
  389. newIndices[i + 1 + ilength] = i1;
  390. newIndices[i + 2 + ilength] = i0;
  391. }
  392. topGeo.attributes.position.values = topBottomPositions;
  393. if (perPositionHeight && vertexFormat.normal) {
  394. var normals = topGeo.attributes.normal.values;
  395. topGeo.attributes.normal.values = new Float32Array(topBottomPositions.length);
  396. topGeo.attributes.normal.values.set(normals);
  397. }
  398. topGeo.indices = newIndices;
  399. } else if (closeBottom) {
  400. numPositions = edgePoints.length / 3;
  401. newIndices = IndexDatatype.IndexDatatype.createTypedArray(numPositions, indices.length);
  402. for (i = 0; i < indices.length; i += 3) {
  403. newIndices[i] = indices[i + 2];
  404. newIndices[i + 1] = indices[i + 1];
  405. newIndices[i + 2] = indices[i];
  406. }
  407. topGeo.indices = newIndices;
  408. }
  409. geos.topAndBottom = new GeometryInstance.GeometryInstance({
  410. geometry : topGeo
  411. });
  412. }
  413. var outerRing = hierarchy.outerRing;
  414. var tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(outerRing, ellipsoid);
  415. var positions2D = tangentPlane.projectPointsOntoPlane(outerRing, createGeometryFromPositionsExtrudedPositions);
  416. var windingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(positions2D);
  417. if (windingOrder === PolygonPipeline.WindingOrder.CLOCKWISE) {
  418. outerRing = outerRing.slice().reverse();
  419. }
  420. var wallGeo;
  421. if(extrudeOutering) {
  422. wallGeo = PolygonGeometryLibrary.PolygonGeometryLibrary.computeWallGeometry(outerRing, ellipsoid, granularity, perPositionHeight, arcType);
  423. geos.walls.push(new GeometryInstance.GeometryInstance({
  424. geometry : wallGeo
  425. }));
  426. }
  427. var holes = hierarchy.holes;
  428. for (i = 0; i < holes.length; i++) {
  429. var hole = holes[i];
  430. tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(hole, ellipsoid);
  431. positions2D = tangentPlane.projectPointsOntoPlane(hole, createGeometryFromPositionsExtrudedPositions);
  432. windingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(positions2D);
  433. if (windingOrder === PolygonPipeline.WindingOrder.COUNTER_CLOCKWISE) {
  434. hole = hole.slice().reverse();
  435. }
  436. wallGeo = PolygonGeometryLibrary.PolygonGeometryLibrary.computeWallGeometry(hole, ellipsoid, granularity, perPositionHeight, arcType);
  437. geos.walls.push(new GeometryInstance.GeometryInstance({
  438. geometry : wallGeo
  439. }));
  440. }
  441. return geos;
  442. }
  443. /**
  444. * A description of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}.
  445. *
  446. * @alias PolygonGeometry
  447. * @constructor
  448. *
  449. * @param {Object} options Object with the following properties:
  450. * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
  451. * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface.
  452. * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface.
  453. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  454. * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise.
  455. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  456. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
  457. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  458. * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open.
  459. * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open.
  460. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}.
  461. *
  462. * @see PolygonGeometry#createGeometry
  463. * @see PolygonGeometry#fromPositions
  464. *
  465. * @demo {@link https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Polygon.html|Cesium Sandcastle Polygon Demo}
  466. *
  467. * @example
  468. * // 1. create a polygon from points
  469. * var polygon = new Cesium.PolygonGeometry({
  470. * polygonHierarchy : new Cesium.PolygonHierarchy(
  471. * Cesium.Cartesian3.fromDegreesArray([
  472. * -72.0, 40.0,
  473. * -70.0, 35.0,
  474. * -75.0, 30.0,
  475. * -70.0, 30.0,
  476. * -68.0, 40.0
  477. * ])
  478. * )
  479. * });
  480. * var geometry = Cesium.PolygonGeometry.createGeometry(polygon);
  481. *
  482. * // 2. create a nested polygon with holes
  483. * var polygonWithHole = new Cesium.PolygonGeometry({
  484. * polygonHierarchy : new Cesium.PolygonHierarchy(
  485. * Cesium.Cartesian3.fromDegreesArray([
  486. * -109.0, 30.0,
  487. * -95.0, 30.0,
  488. * -95.0, 40.0,
  489. * -109.0, 40.0
  490. * ]),
  491. * [new Cesium.PolygonHierarchy(
  492. * Cesium.Cartesian3.fromDegreesArray([
  493. * -107.0, 31.0,
  494. * -107.0, 39.0,
  495. * -97.0, 39.0,
  496. * -97.0, 31.0
  497. * ]),
  498. * [new Cesium.PolygonHierarchy(
  499. * Cesium.Cartesian3.fromDegreesArray([
  500. * -105.0, 33.0,
  501. * -99.0, 33.0,
  502. * -99.0, 37.0,
  503. * -105.0, 37.0
  504. * ]),
  505. * [new Cesium.PolygonHierarchy(
  506. * Cesium.Cartesian3.fromDegreesArray([
  507. * -103.0, 34.0,
  508. * -101.0, 34.0,
  509. * -101.0, 36.0,
  510. * -103.0, 36.0
  511. * ])
  512. * )]
  513. * )]
  514. * )]
  515. * )
  516. * });
  517. * var geometry = Cesium.PolygonGeometry.createGeometry(polygonWithHole);
  518. *
  519. * // 3. create extruded polygon
  520. * var extrudedPolygon = new Cesium.PolygonGeometry({
  521. * polygonHierarchy : new Cesium.PolygonHierarchy(
  522. * Cesium.Cartesian3.fromDegreesArray([
  523. * -72.0, 40.0,
  524. * -70.0, 35.0,
  525. * -75.0, 30.0,
  526. * -70.0, 30.0,
  527. * -68.0, 40.0
  528. * ])
  529. * ),
  530. * extrudedHeight: 300000
  531. * });
  532. * var geometry = Cesium.PolygonGeometry.createGeometry(extrudedPolygon);
  533. */
  534. function PolygonGeometry(options) {
  535. //>>includeStart('debug', pragmas.debug);
  536. Check.Check.typeOf.object('options', options);
  537. Check.Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy);
  538. if (when.defined(options.perPositionHeight) && options.perPositionHeight && when.defined(options.height)) {
  539. throw new Check.DeveloperError('Cannot use both options.perPositionHeight and options.height');
  540. }
  541. if (when.defined(options.arcType) && options.arcType !== ArcType.ArcType.GEODESIC && options.arcType !== ArcType.ArcType.RHUMB) {
  542. throw new Check.DeveloperError('Invalid arcType. Valid options are ArcType.GEODESIC and ArcType.RHUMB.');
  543. }
  544. //>>includeEnd('debug');
  545. var polygonHierarchy = options.polygonHierarchy;
  546. var vertexFormat = when.defaultValue(options.vertexFormat, VertexFormat.VertexFormat.DEFAULT);
  547. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  548. var granularity = when.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  549. var stRotation = when.defaultValue(options.stRotation, 0.0);
  550. var perPositionHeight = when.defaultValue(options.perPositionHeight, false);
  551. var perPositionHeightExtrude = perPositionHeight && when.defined(options.extrudedHeight);
  552. var height = when.defaultValue(options.height, 0.0);
  553. var extrudedHeight = when.defaultValue(options.extrudedHeight, height);
  554. if (!perPositionHeightExtrude) {
  555. var h = Math.max(height, extrudedHeight);
  556. extrudedHeight = Math.min(height, extrudedHeight);
  557. height = h;
  558. }
  559. this._vertexFormat = VertexFormat.VertexFormat.clone(vertexFormat);
  560. this._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid);
  561. this._granularity = granularity;
  562. this._stRotation = stRotation;
  563. this._height = height;
  564. this._extrudedHeight = extrudedHeight;
  565. this._closeTop = when.defaultValue(options.closeTop, true);
  566. this._closeBottom = when.defaultValue(options.closeBottom, true);
  567. this._extrudeOutering = when.defaultValue(options.extrudeOutering, true);
  568. this._polygonHierarchy = polygonHierarchy;
  569. this._perPositionHeight = perPositionHeight;
  570. this._perPositionHeightExtrude = perPositionHeightExtrude;
  571. this._shadowVolume = when.defaultValue(options.shadowVolume, false);
  572. this._workerName = 'createPolygonGeometry';
  573. this._offsetAttribute = options.offsetAttribute;
  574. this._arcType = when.defaultValue(options.arcType, ArcType.ArcType.GEODESIC);
  575. this._rectangle = undefined;
  576. this._textureCoordinateRotationPoints = undefined;
  577. /**
  578. * The number of elements used to pack the object into an array.
  579. * @type {Number}
  580. */
  581. this.packedLength = PolygonGeometryLibrary.PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Cartesian2.Ellipsoid.packedLength + VertexFormat.VertexFormat.packedLength + 12;
  582. }
  583. /**
  584. * A description of a polygon from an array of positions. Polygon geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}.
  585. *
  586. * @param {Object} options Object with the following properties:
  587. * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon.
  588. * @param {Number} [options.height=0.0] The height of the polygon.
  589. * @param {Number} [options.extrudedHeight] The height of the polygon extrusion.
  590. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  591. * @param {Number} [options.stRotation=0.0] The rotation of the texture coordinates, in radians. A positive rotation is counter-clockwise.
  592. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  593. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
  594. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  595. * @param {Boolean} [options.closeTop=true] When false, leaves off the top of an extruded polygon open.
  596. * @param {Boolean} [options.closeBottom=true] When false, leaves off the bottom of an extruded polygon open.
  597. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}.
  598. * @returns {PolygonGeometry}
  599. *
  600. *
  601. * @example
  602. * // create a polygon from points
  603. * var polygon = Cesium.PolygonGeometry.fromPositions({
  604. * positions : Cesium.Cartesian3.fromDegreesArray([
  605. * -72.0, 40.0,
  606. * -70.0, 35.0,
  607. * -75.0, 30.0,
  608. * -70.0, 30.0,
  609. * -68.0, 40.0
  610. * ])
  611. * });
  612. * var geometry = Cesium.PolygonGeometry.createGeometry(polygon);
  613. *
  614. * @see PolygonGeometry#createGeometry
  615. */
  616. PolygonGeometry.fromPositions = function(options) {
  617. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  618. //>>includeStart('debug', pragmas.debug);
  619. Check.Check.defined('options.positions', options.positions);
  620. //>>includeEnd('debug');
  621. var newOptions = {
  622. polygonHierarchy : {
  623. positions : options.positions
  624. },
  625. height : options.height,
  626. extrudedHeight : options.extrudedHeight,
  627. vertexFormat : options.vertexFormat,
  628. stRotation : options.stRotation,
  629. ellipsoid : options.ellipsoid,
  630. granularity : options.granularity,
  631. perPositionHeight : options.perPositionHeight,
  632. closeTop : options.closeTop,
  633. closeBottom : options.closeBottom,
  634. offsetAttribute : options.offsetAttribute,
  635. arcType : options.arcType
  636. };
  637. return new PolygonGeometry(newOptions);
  638. };
  639. /**
  640. * Stores the provided instance into the provided array.
  641. *
  642. * @param {PolygonGeometry} value The value to pack.
  643. * @param {Number[]} array The array to pack into.
  644. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  645. *
  646. * @returns {Number[]} The array that was packed into
  647. */
  648. PolygonGeometry.pack = function(value, array, startingIndex) {
  649. //>>includeStart('debug', pragmas.debug);
  650. Check.Check.typeOf.object('value', value);
  651. Check.Check.defined('array', array);
  652. //>>includeEnd('debug');
  653. startingIndex = when.defaultValue(startingIndex, 0);
  654. startingIndex = PolygonGeometryLibrary.PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex);
  655. Cartesian2.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  656. startingIndex += Cartesian2.Ellipsoid.packedLength;
  657. VertexFormat.VertexFormat.pack(value._vertexFormat, array, startingIndex);
  658. startingIndex += VertexFormat.VertexFormat.packedLength;
  659. array[startingIndex++] = value._height;
  660. array[startingIndex++] = value._extrudedHeight;
  661. array[startingIndex++] = value._granularity;
  662. array[startingIndex++] = value._stRotation;
  663. array[startingIndex++] = value._perPositionHeightExtrude ? 1.0 : 0.0;
  664. array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0;
  665. array[startingIndex++] = value._closeTop ? 1.0 : 0.0;
  666. array[startingIndex++] = value._closeBottom ? 1.0 : 0.0;
  667. array[startingIndex++] = value._shadowVolume ? 1.0 : 0.0;
  668. array[startingIndex++] = when.defaultValue(value._offsetAttribute, -1);
  669. array[startingIndex++] = value._arcType;
  670. array[startingIndex] = value.packedLength;
  671. return array;
  672. };
  673. var scratchEllipsoid = Cartesian2.Ellipsoid.clone(Cartesian2.Ellipsoid.UNIT_SPHERE);
  674. var scratchVertexFormat = new VertexFormat.VertexFormat();
  675. //Only used to avoid inability to default construct.
  676. var dummyOptions = {
  677. polygonHierarchy : {}
  678. };
  679. /**
  680. * Retrieves an instance from a packed array.
  681. *
  682. * @param {Number[]} array The packed array.
  683. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  684. * @param {PolygonGeometry} [result] The object into which to store the result.
  685. */
  686. PolygonGeometry.unpack = function(array, startingIndex, result) {
  687. //>>includeStart('debug', pragmas.debug);
  688. Check.Check.defined('array', array);
  689. //>>includeEnd('debug');
  690. startingIndex = when.defaultValue(startingIndex, 0);
  691. var polygonHierarchy = PolygonGeometryLibrary.PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex);
  692. startingIndex = polygonHierarchy.startingIndex;
  693. delete polygonHierarchy.startingIndex;
  694. var ellipsoid = Cartesian2.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  695. startingIndex += Cartesian2.Ellipsoid.packedLength;
  696. var vertexFormat = VertexFormat.VertexFormat.unpack(array, startingIndex, scratchVertexFormat);
  697. startingIndex += VertexFormat.VertexFormat.packedLength;
  698. var height = array[startingIndex++];
  699. var extrudedHeight = array[startingIndex++];
  700. var granularity = array[startingIndex++];
  701. var stRotation = array[startingIndex++];
  702. var perPositionHeightExtrude = array[startingIndex++] === 1.0;
  703. var perPositionHeight = array[startingIndex++] === 1.0;
  704. var closeTop = array[startingIndex++] === 1.0;
  705. var closeBottom = array[startingIndex++] === 1.0;
  706. var shadowVolume = array[startingIndex++] === 1.0;
  707. var offsetAttribute = array[startingIndex++];
  708. var arcType = array[startingIndex++];
  709. var packedLength = array[startingIndex];
  710. if (!when.defined(result)) {
  711. result = new PolygonGeometry(dummyOptions);
  712. }
  713. result._polygonHierarchy = polygonHierarchy;
  714. result._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  715. result._vertexFormat = VertexFormat.VertexFormat.clone(vertexFormat, result._vertexFormat);
  716. result._height = height;
  717. result._extrudedHeight = extrudedHeight;
  718. result._granularity = granularity;
  719. result._stRotation = stRotation;
  720. result._perPositionHeightExtrude = perPositionHeightExtrude;
  721. result._perPositionHeight = perPositionHeight;
  722. result._closeTop = closeTop;
  723. result._closeBottom = closeBottom;
  724. result._shadowVolume = shadowVolume;
  725. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  726. result._arcType = arcType;
  727. result.packedLength = packedLength;
  728. return result;
  729. };
  730. /**
  731. * Returns the bounding rectangle given the provided options
  732. *
  733. * @param {Object} options Object with the following properties:
  734. * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
  735. * @param {Number} [options.granularity=CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions sampled.
  736. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of line the polygon edges must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}.
  737. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  738. * @param {Rectangle} [result] An object in which to store the result.
  739. *
  740. * @returns {Rectangle} The result rectangle
  741. */
  742. PolygonGeometry.computeRectangle = function(options, result) {
  743. //>>includeStart('debug', pragmas.debug);
  744. Check.Check.typeOf.object('options', options);
  745. Check.Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy);
  746. //>>includeEnd('debug');
  747. var granularity = when.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  748. var arcType = when.defaultValue(options.arcType, ArcType.ArcType.GEODESIC);
  749. //>>includeStart('debug', pragmas.debug);
  750. if (arcType !== ArcType.ArcType.GEODESIC && arcType !== ArcType.ArcType.RHUMB) {
  751. throw new Check.DeveloperError('Invalid arcType. Valid options are ArcType.GEODESIC and ArcType.RHUMB.');
  752. }
  753. //>>includeEnd('debug');
  754. var polygonHierarchy = options.polygonHierarchy;
  755. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  756. return computeRectangle(polygonHierarchy.positions, ellipsoid, arcType, granularity, result);
  757. };
  758. /**
  759. * Computes the geometric representation of a polygon, including its vertices, indices, and a bounding sphere.
  760. *
  761. * @param {PolygonGeometry} polygonGeometry A description of the polygon.
  762. * @returns {Geometry|undefined} The computed vertices and indices.
  763. */
  764. PolygonGeometry.createGeometry = function(polygonGeometry) {
  765. var vertexFormat = polygonGeometry._vertexFormat;
  766. var ellipsoid = polygonGeometry._ellipsoid;
  767. var granularity = polygonGeometry._granularity;
  768. var stRotation = polygonGeometry._stRotation;
  769. var polygonHierarchy = polygonGeometry._polygonHierarchy;
  770. var perPositionHeight = polygonGeometry._perPositionHeight;
  771. var closeTop = polygonGeometry._closeTop;
  772. var closeBottom = polygonGeometry._closeBottom;
  773. var arcType = polygonGeometry._arcType;
  774. var outerPositions = polygonHierarchy.positions;
  775. if (outerPositions.length < 3) {
  776. return;
  777. }
  778. var tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(outerPositions, ellipsoid);
  779. var results = PolygonGeometryLibrary.PolygonGeometryLibrary.polygonsFromHierarchy(polygonHierarchy, tangentPlane.projectPointsOntoPlane.bind(tangentPlane), !perPositionHeight, ellipsoid);
  780. var hierarchy = results.hierarchy;
  781. var polygons = results.polygons;
  782. if (hierarchy.length === 0) {
  783. return;
  784. }
  785. outerPositions = hierarchy[0].outerRing;
  786. var boundingRectangle = PolygonGeometryLibrary.PolygonGeometryLibrary.computeBoundingRectangle(tangentPlane.plane.normal, tangentPlane.projectPointOntoPlane.bind(tangentPlane), outerPositions, stRotation, scratchBoundingRectangle);
  787. var geometries = [];
  788. var height = polygonGeometry._height;
  789. var extrudedHeight = polygonGeometry._extrudedHeight;
  790. var extrude = polygonGeometry._perPositionHeightExtrude || !_Math.CesiumMath.equalsEpsilon(height, extrudedHeight, 0, _Math.CesiumMath.EPSILON2);
  791. var options = {
  792. perPositionHeight: perPositionHeight,
  793. vertexFormat: vertexFormat,
  794. geometry: undefined,
  795. tangentPlane: tangentPlane,
  796. boundingRectangle: boundingRectangle,
  797. ellipsoid: ellipsoid,
  798. stRotation: stRotation,
  799. bottom: false,
  800. top: true,
  801. wall: false,
  802. extrude: false,
  803. arcType: arcType
  804. };
  805. var i;
  806. if (extrude) {
  807. options.extrude = true;
  808. options.top = closeTop;
  809. options.bottom = closeBottom;
  810. options.shadowVolume = polygonGeometry._shadowVolume;
  811. options.offsetAttribute = polygonGeometry._offsetAttribute;
  812. for (i = 0; i < polygons.length; i++) {
  813. var splitGeometry = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], granularity, hierarchy[i], perPositionHeight, closeTop, closeBottom, vertexFormat, arcType, polygonGeometry._extrudeOutering);
  814. var topAndBottom;
  815. if (closeTop && closeBottom) {
  816. topAndBottom = splitGeometry.topAndBottom;
  817. options.geometry = PolygonGeometryLibrary.PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(topAndBottom.geometry, height, extrudedHeight, ellipsoid, perPositionHeight);
  818. } else if (closeTop) {
  819. topAndBottom = splitGeometry.topAndBottom;
  820. topAndBottom.geometry.attributes.position.values = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight);
  821. options.geometry = topAndBottom.geometry;
  822. } else if (closeBottom) {
  823. topAndBottom = splitGeometry.topAndBottom;
  824. topAndBottom.geometry.attributes.position.values = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(topAndBottom.geometry.attributes.position.values, extrudedHeight, ellipsoid, true);
  825. options.geometry = topAndBottom.geometry;
  826. }
  827. if (closeTop || closeBottom) {
  828. options.wall = false;
  829. topAndBottom.geometry = computeAttributes(options);
  830. geometries.push(topAndBottom);
  831. }
  832. var walls = splitGeometry.walls;
  833. options.wall = true;
  834. for ( var k = 0; k < walls.length; k++) {
  835. var wall = walls[k];
  836. options.geometry = PolygonGeometryLibrary.PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(wall.geometry, height, extrudedHeight, ellipsoid, perPositionHeight);
  837. wall.geometry = computeAttributes(options);
  838. geometries.push(wall);
  839. }
  840. }
  841. } else {
  842. for (i = 0; i < polygons.length; i++) {
  843. var geometryInstance = new GeometryInstance.GeometryInstance({
  844. geometry : PolygonGeometryLibrary.PolygonGeometryLibrary.createGeometryFromPositions(ellipsoid, polygons[i], granularity, perPositionHeight, vertexFormat, arcType)
  845. });
  846. geometryInstance.geometry.attributes.position.values = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(geometryInstance.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight);
  847. options.geometry = geometryInstance.geometry;
  848. geometryInstance.geometry = computeAttributes(options);
  849. if (when.defined(polygonGeometry._offsetAttribute)) {
  850. var length = geometryInstance.geometry.attributes.position.values.length;
  851. var applyOffset = new Uint8Array(length / 3);
  852. var offsetValue = polygonGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  853. GeometryOffsetAttribute.arrayFill(applyOffset, offsetValue);
  854. geometryInstance.geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  855. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  856. componentsPerAttribute : 1,
  857. values: applyOffset
  858. });
  859. }
  860. geometries.push(geometryInstance);
  861. }
  862. }
  863. var geometry = GeometryPipeline.GeometryPipeline.combineInstances(geometries)[0];
  864. geometry.attributes.position.values = new Float64Array(geometry.attributes.position.values);
  865. geometry.indices = IndexDatatype.IndexDatatype.createTypedArray(geometry.attributes.position.values.length / 3, geometry.indices);
  866. var attributes = geometry.attributes;
  867. var boundingSphere = BoundingSphere.BoundingSphere.fromVertices(attributes.position.values);
  868. if (!vertexFormat.position) {
  869. delete attributes.position;
  870. }
  871. return new GeometryAttribute.Geometry({
  872. attributes : attributes,
  873. indices : geometry.indices,
  874. primitiveType : geometry.primitiveType,
  875. boundingSphere : boundingSphere,
  876. offsetAttribute : polygonGeometry._offsetAttribute
  877. });
  878. };
  879. /**
  880. * @private
  881. */
  882. PolygonGeometry.createShadowVolume = function(polygonGeometry, minHeightFunc, maxHeightFunc) {
  883. var granularity = polygonGeometry._granularity;
  884. var ellipsoid = polygonGeometry._ellipsoid;
  885. var minHeight = minHeightFunc(granularity, ellipsoid);
  886. var maxHeight = maxHeightFunc(granularity, ellipsoid);
  887. return new PolygonGeometry({
  888. polygonHierarchy : polygonGeometry._polygonHierarchy,
  889. ellipsoid : ellipsoid,
  890. stRotation : polygonGeometry._stRotation,
  891. granularity : granularity,
  892. perPositionHeight : false,
  893. extrudedHeight : minHeight,
  894. height : maxHeight,
  895. vertexFormat : VertexFormat.VertexFormat.POSITION_ONLY,
  896. shadowVolume: true,
  897. arcType : polygonGeometry._arcType
  898. });
  899. };
  900. function textureCoordinateRotationPoints(polygonGeometry) {
  901. var stRotation = -polygonGeometry._stRotation;
  902. if (stRotation === 0.0) {
  903. return [0, 0, 0, 1, 1, 0];
  904. }
  905. var ellipsoid = polygonGeometry._ellipsoid;
  906. var positions = polygonGeometry._polygonHierarchy.positions;
  907. var boundingRectangle = polygonGeometry.rectangle;
  908. return GeometryAttribute.Geometry._textureCoordinateRotationPoints(positions, stRotation, ellipsoid, boundingRectangle);
  909. }
  910. Object.defineProperties(PolygonGeometry.prototype, {
  911. /**
  912. * @private
  913. */
  914. rectangle : {
  915. get : function() {
  916. if (!when.defined(this._rectangle)) {
  917. var positions = this._polygonHierarchy.positions;
  918. this._rectangle = computeRectangle(positions, this._ellipsoid, this._arcType, this._granularity);
  919. }
  920. return this._rectangle;
  921. }
  922. },
  923. /**
  924. * For remapping texture coordinates when rendering PolygonGeometries as GroundPrimitives.
  925. * @private
  926. */
  927. textureCoordinateRotationPoints : {
  928. get : function() {
  929. if (!when.defined(this._textureCoordinateRotationPoints)) {
  930. this._textureCoordinateRotationPoints = textureCoordinateRotationPoints(this);
  931. }
  932. return this._textureCoordinateRotationPoints;
  933. }
  934. }
  935. });
  936. function createPolygonGeometry(polygonGeometry, offset) {
  937. if (when.defined(offset)) {
  938. polygonGeometry = PolygonGeometry.unpack(polygonGeometry, offset);
  939. }
  940. polygonGeometry._ellipsoid = Cartesian2.Ellipsoid.clone(polygonGeometry._ellipsoid);
  941. return PolygonGeometry.createGeometry(polygonGeometry);
  942. }
  943. return createPolygonGeometry;
  944. });