createCorridorGeometry.js 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['./defined-26bd4a03', './Check-da037458', './freezeObject-2d83f591', './defaultValue-f2e68450', './Math-fa6e45cb', './Cartesian2-2a723276', './defineProperties-6f7a50f2', './Transforms-65aba0a4', './RuntimeError-ad75c885', './WebGLConstants-497deb20', './ComponentDatatype-69643096', './GeometryAttribute-ed359d71', './when-ee12a2cb', './GeometryAttributes-eecc9f43', './IndexDatatype-3de60176', './IntersectionTests-c2360ffa', './Plane-a1a3fd52', './GeometryOffsetAttribute-cb30cd97', './VertexFormat-fbb91dc7', './arrayRemoveDuplicates-dd708d81', './EllipsoidTangentPlane-10c6053a', './EllipsoidRhumbLine-c6cdbfd3', './PolygonPipeline-e486c11c', './PolylineVolumeGeometryLibrary-57289189', './EllipsoidGeodesic-53e988a6', './PolylinePipeline-b4161aaf', './CorridorGeometryLibrary-b584c522'], function (defined, Check, freezeObject, defaultValue, _Math, Cartesian2, defineProperties, Transforms, RuntimeError, WebGLConstants, ComponentDatatype, GeometryAttribute, when, GeometryAttributes, IndexDatatype, IntersectionTests, Plane, GeometryOffsetAttribute, VertexFormat, arrayRemoveDuplicates, EllipsoidTangentPlane, EllipsoidRhumbLine, PolygonPipeline, PolylineVolumeGeometryLibrary, EllipsoidGeodesic, PolylinePipeline, CorridorGeometryLibrary) { 'use strict';
  3. var cartesian1 = new Cartesian2.Cartesian3();
  4. var cartesian2 = new Cartesian2.Cartesian3();
  5. var cartesian3 = new Cartesian2.Cartesian3();
  6. var cartesian4 = new Cartesian2.Cartesian3();
  7. var cartesian5 = new Cartesian2.Cartesian3();
  8. var cartesian6 = new Cartesian2.Cartesian3();
  9. var scratch1 = new Cartesian2.Cartesian3();
  10. var scratch2 = new Cartesian2.Cartesian3();
  11. function scaleToSurface(positions, ellipsoid) {
  12. for (var i = 0; i < positions.length; i++) {
  13. positions[i] = ellipsoid.scaleToGeodeticSurface(positions[i], positions[i]);
  14. }
  15. return positions;
  16. }
  17. function addNormals(attr, normal, left, front, back, vertexFormat) {
  18. var normals = attr.normals;
  19. var tangents = attr.tangents;
  20. var bitangents = attr.bitangents;
  21. var forward = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.cross(left, normal, scratch1), scratch1);
  22. if (vertexFormat.normal) {
  23. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(normals, normal, front, back);
  24. }
  25. if (vertexFormat.tangent) {
  26. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(tangents, forward, front, back);
  27. }
  28. if (vertexFormat.bitangent) {
  29. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(bitangents, left, front, back);
  30. }
  31. }
  32. function combine(computedPositions, vertexFormat, ellipsoid) {
  33. var positions = computedPositions.positions;
  34. var corners = computedPositions.corners;
  35. var endPositions = computedPositions.endPositions;
  36. var computedLefts = computedPositions.lefts;
  37. var computedNormals = computedPositions.normals;
  38. var attributes = new GeometryAttributes.GeometryAttributes();
  39. var corner;
  40. var leftCount = 0;
  41. var rightCount = 0;
  42. var i;
  43. var indicesLength = 0;
  44. var length;
  45. for (i = 0; i < positions.length; i += 2) {
  46. length = positions[i].length - 3;
  47. leftCount += length; //subtracting 3 to account for duplicate points at corners
  48. indicesLength += length*2;
  49. rightCount += positions[i + 1].length - 3;
  50. }
  51. leftCount += 3; //add back count for end positions
  52. rightCount += 3;
  53. for (i = 0; i < corners.length; i++) {
  54. corner = corners[i];
  55. var leftSide = corners[i].leftPositions;
  56. if (defined.defined(leftSide)) {
  57. length = leftSide.length;
  58. leftCount += length;
  59. indicesLength += length;
  60. } else {
  61. length = corners[i].rightPositions.length;
  62. rightCount += length;
  63. indicesLength += length;
  64. }
  65. }
  66. var addEndPositions = defined.defined(endPositions);
  67. var endPositionLength;
  68. if (addEndPositions) {
  69. endPositionLength = endPositions[0].length - 3;
  70. leftCount += endPositionLength;
  71. rightCount += endPositionLength;
  72. endPositionLength /= 3;
  73. indicesLength += endPositionLength * 6;
  74. }
  75. var size = leftCount + rightCount;
  76. var finalPositions = new Float64Array(size);
  77. var normals = (vertexFormat.normal) ? new Float32Array(size) : undefined;
  78. var tangents = (vertexFormat.tangent) ? new Float32Array(size) : undefined;
  79. var bitangents = (vertexFormat.bitangent) ? new Float32Array(size) : undefined;
  80. var attr = {
  81. normals : normals,
  82. tangents : tangents,
  83. bitangents : bitangents
  84. };
  85. var front = 0;
  86. var back = size - 1;
  87. var UL, LL, UR, LR;
  88. var normal = cartesian1;
  89. var left = cartesian2;
  90. var rightPos, leftPos;
  91. var halfLength = endPositionLength / 2;
  92. var indices = IndexDatatype.IndexDatatype.createTypedArray(size / 3, indicesLength);
  93. var index = 0;
  94. if (addEndPositions) { // add rounded end
  95. leftPos = cartesian3;
  96. rightPos = cartesian4;
  97. var firstEndPositions = endPositions[0];
  98. normal = Cartesian2.Cartesian3.fromArray(computedNormals, 0, normal);
  99. left = Cartesian2.Cartesian3.fromArray(computedLefts, 0, left);
  100. for (i = 0; i < halfLength; i++) {
  101. leftPos = Cartesian2.Cartesian3.fromArray(firstEndPositions, (halfLength - 1 - i) * 3, leftPos);
  102. rightPos = Cartesian2.Cartesian3.fromArray(firstEndPositions, (halfLength + i) * 3, rightPos);
  103. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front);
  104. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back);
  105. addNormals(attr, normal, left, front, back, vertexFormat);
  106. LL = front / 3;
  107. LR = LL + 1;
  108. UL = (back - 2) / 3;
  109. UR = UL - 1;
  110. indices[index++] = UL;
  111. indices[index++] = LL;
  112. indices[index++] = UR;
  113. indices[index++] = UR;
  114. indices[index++] = LL;
  115. indices[index++] = LR;
  116. front += 3;
  117. back -= 3;
  118. }
  119. }
  120. var posIndex = 0;
  121. var compIndex = 0;
  122. var rightEdge = positions[posIndex++]; //add first two edges
  123. var leftEdge = positions[posIndex++];
  124. finalPositions.set(rightEdge, front);
  125. finalPositions.set(leftEdge, back - leftEdge.length + 1);
  126. left = Cartesian2.Cartesian3.fromArray(computedLefts, compIndex, left);
  127. var rightNormal;
  128. var leftNormal;
  129. length = leftEdge.length - 3;
  130. for (i = 0; i < length; i += 3) {
  131. rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(rightEdge, i, scratch1), scratch1);
  132. leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(leftEdge, length - i, scratch2), scratch2);
  133. normal = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.add(rightNormal, leftNormal, normal), normal);
  134. addNormals(attr, normal, left, front, back, vertexFormat);
  135. LL = front / 3;
  136. LR = LL + 1;
  137. UL = (back - 2) / 3;
  138. UR = UL - 1;
  139. indices[index++] = UL;
  140. indices[index++] = LL;
  141. indices[index++] = UR;
  142. indices[index++] = UR;
  143. indices[index++] = LL;
  144. indices[index++] = LR;
  145. front += 3;
  146. back -= 3;
  147. }
  148. rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(rightEdge, length, scratch1), scratch1);
  149. leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(leftEdge, length, scratch2), scratch2);
  150. normal = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.add(rightNormal, leftNormal, normal), normal);
  151. compIndex += 3;
  152. for (i = 0; i < corners.length; i++) {
  153. var j;
  154. corner = corners[i];
  155. var l = corner.leftPositions;
  156. var r = corner.rightPositions;
  157. var pivot;
  158. var start;
  159. var outsidePoint = cartesian6;
  160. var previousPoint = cartesian3;
  161. var nextPoint = cartesian4;
  162. normal = Cartesian2.Cartesian3.fromArray(computedNormals, compIndex, normal);
  163. if (defined.defined(l)) {
  164. addNormals(attr, normal, left, undefined, back, vertexFormat);
  165. back -= 3;
  166. pivot = LR;
  167. start = UR;
  168. for (j = 0; j < l.length / 3; j++) {
  169. outsidePoint = Cartesian2.Cartesian3.fromArray(l, j * 3, outsidePoint);
  170. indices[index++] = pivot;
  171. indices[index++] = start - j - 1;
  172. indices[index++] = start - j;
  173. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, undefined, back);
  174. previousPoint = Cartesian2.Cartesian3.fromArray(finalPositions, (start - j - 1) * 3, previousPoint);
  175. nextPoint = Cartesian2.Cartesian3.fromArray(finalPositions, pivot * 3, nextPoint);
  176. left = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.subtract(previousPoint, nextPoint, left), left);
  177. addNormals(attr, normal, left, undefined, back, vertexFormat);
  178. back -= 3;
  179. }
  180. outsidePoint = Cartesian2.Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint);
  181. previousPoint = Cartesian2.Cartesian3.subtract(Cartesian2.Cartesian3.fromArray(finalPositions, (start) * 3, previousPoint), outsidePoint, previousPoint);
  182. nextPoint = Cartesian2.Cartesian3.subtract(Cartesian2.Cartesian3.fromArray(finalPositions, (start - j) * 3, nextPoint), outsidePoint, nextPoint);
  183. left = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.add(previousPoint, nextPoint, left), left);
  184. addNormals(attr, normal, left, front, undefined, vertexFormat);
  185. front += 3;
  186. } else {
  187. addNormals(attr, normal, left, front, undefined, vertexFormat);
  188. front += 3;
  189. pivot = UR;
  190. start = LR;
  191. for (j = 0; j < r.length / 3; j++) {
  192. outsidePoint = Cartesian2.Cartesian3.fromArray(r, j * 3, outsidePoint);
  193. indices[index++] = pivot;
  194. indices[index++] = start + j;
  195. indices[index++] = start + j + 1;
  196. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, outsidePoint, front);
  197. previousPoint = Cartesian2.Cartesian3.fromArray(finalPositions, pivot * 3, previousPoint);
  198. nextPoint = Cartesian2.Cartesian3.fromArray(finalPositions, (start + j) * 3, nextPoint);
  199. left = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.subtract(previousPoint, nextPoint, left), left);
  200. addNormals(attr, normal, left, front, undefined, vertexFormat);
  201. front += 3;
  202. }
  203. outsidePoint = Cartesian2.Cartesian3.fromArray(finalPositions, pivot * 3, outsidePoint);
  204. previousPoint = Cartesian2.Cartesian3.subtract(Cartesian2.Cartesian3.fromArray(finalPositions, (start + j) * 3, previousPoint), outsidePoint, previousPoint);
  205. nextPoint = Cartesian2.Cartesian3.subtract(Cartesian2.Cartesian3.fromArray(finalPositions, start * 3, nextPoint), outsidePoint, nextPoint);
  206. left = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.negate(Cartesian2.Cartesian3.add(nextPoint, previousPoint, left), left), left);
  207. addNormals(attr, normal, left, undefined, back, vertexFormat);
  208. back -= 3;
  209. }
  210. rightEdge = positions[posIndex++];
  211. leftEdge = positions[posIndex++];
  212. rightEdge.splice(0, 3); //remove duplicate points added by corner
  213. leftEdge.splice(leftEdge.length - 3, 3);
  214. finalPositions.set(rightEdge, front);
  215. finalPositions.set(leftEdge, back - leftEdge.length + 1);
  216. length = leftEdge.length - 3;
  217. compIndex += 3;
  218. left = Cartesian2.Cartesian3.fromArray(computedLefts, compIndex, left);
  219. for (j = 0; j < leftEdge.length; j += 3) {
  220. rightNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(rightEdge, j, scratch1), scratch1);
  221. leftNormal = ellipsoid.geodeticSurfaceNormal(Cartesian2.Cartesian3.fromArray(leftEdge, length - j, scratch2), scratch2);
  222. normal = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.add(rightNormal, leftNormal, normal), normal);
  223. addNormals(attr, normal, left, front, back, vertexFormat);
  224. LR = front / 3;
  225. LL = LR - 1;
  226. UR = (back - 2) / 3;
  227. UL = UR + 1;
  228. indices[index++] = UL;
  229. indices[index++] = LL;
  230. indices[index++] = UR;
  231. indices[index++] = UR;
  232. indices[index++] = LL;
  233. indices[index++] = LR;
  234. front += 3;
  235. back -= 3;
  236. }
  237. front -= 3;
  238. back += 3;
  239. }
  240. normal = Cartesian2.Cartesian3.fromArray(computedNormals, computedNormals.length - 3, normal);
  241. addNormals(attr, normal, left, front, back, vertexFormat);
  242. if (addEndPositions) { // add rounded end
  243. front += 3;
  244. back -= 3;
  245. leftPos = cartesian3;
  246. rightPos = cartesian4;
  247. var lastEndPositions = endPositions[1];
  248. for (i = 0; i < halfLength; i++) {
  249. leftPos = Cartesian2.Cartesian3.fromArray(lastEndPositions, (endPositionLength - i - 1) * 3, leftPos);
  250. rightPos = Cartesian2.Cartesian3.fromArray(lastEndPositions, i * 3, rightPos);
  251. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, leftPos, undefined, back);
  252. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(finalPositions, rightPos, front);
  253. addNormals(attr, normal, left, front, back, vertexFormat);
  254. LR = front / 3;
  255. LL = LR - 1;
  256. UR = (back - 2) / 3;
  257. UL = UR + 1;
  258. indices[index++] = UL;
  259. indices[index++] = LL;
  260. indices[index++] = UR;
  261. indices[index++] = UR;
  262. indices[index++] = LL;
  263. indices[index++] = LR;
  264. front += 3;
  265. back -= 3;
  266. }
  267. }
  268. attributes.position = new GeometryAttribute.GeometryAttribute({
  269. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  270. componentsPerAttribute : 3,
  271. values : finalPositions
  272. });
  273. if (vertexFormat.st) {
  274. var st = new Float32Array(size / 3 * 2);
  275. var rightSt;
  276. var leftSt;
  277. var stIndex = 0;
  278. if (addEndPositions) {
  279. leftCount /= 3;
  280. rightCount /= 3;
  281. var theta = Math.PI / (endPositionLength + 1);
  282. leftSt = 1 / (leftCount - endPositionLength + 1);
  283. rightSt = 1 / (rightCount - endPositionLength + 1);
  284. var a;
  285. var halfEndPos = endPositionLength / 2;
  286. for (i = halfEndPos + 1; i < endPositionLength + 1; i++) { // lower left rounded end
  287. a = _Math.CesiumMath.PI_OVER_TWO + theta * i;
  288. st[stIndex++] = rightSt * (1 + Math.cos(a));
  289. st[stIndex++] = 0.5 * (1 + Math.sin(a));
  290. }
  291. for (i = 1; i < rightCount - endPositionLength + 1; i++) { // bottom edge
  292. st[stIndex++] = i * rightSt;
  293. st[stIndex++] = 0;
  294. }
  295. for (i = endPositionLength; i > halfEndPos; i--) { // lower right rounded end
  296. a = _Math.CesiumMath.PI_OVER_TWO - i * theta;
  297. st[stIndex++] = 1 - rightSt * (1 + Math.cos(a));
  298. st[stIndex++] = 0.5 * (1 + Math.sin(a));
  299. }
  300. for (i = halfEndPos; i > 0; i--) { // upper right rounded end
  301. a = _Math.CesiumMath.PI_OVER_TWO - theta * i;
  302. st[stIndex++] = 1 - leftSt * (1 + Math.cos(a));
  303. st[stIndex++] = 0.5 * (1 + Math.sin(a));
  304. }
  305. for (i = leftCount - endPositionLength; i > 0; i--) { // top edge
  306. st[stIndex++] = i * leftSt;
  307. st[stIndex++] = 1;
  308. }
  309. for (i = 1; i < halfEndPos + 1; i++) { // upper left rounded end
  310. a = _Math.CesiumMath.PI_OVER_TWO + theta * i;
  311. st[stIndex++] = leftSt * (1 + Math.cos(a));
  312. st[stIndex++] = 0.5 * (1 + Math.sin(a));
  313. }
  314. } else {
  315. leftCount /= 3;
  316. rightCount /= 3;
  317. leftSt = 1 / (leftCount - 1);
  318. rightSt = 1 / (rightCount - 1);
  319. for (i = 0; i < rightCount; i++) { // bottom edge
  320. st[stIndex++] = i * rightSt;
  321. st[stIndex++] = 0;
  322. }
  323. for (i = leftCount; i > 0; i--) { // top edge
  324. st[stIndex++] = (i - 1) * leftSt;
  325. st[stIndex++] = 1;
  326. }
  327. }
  328. attributes.st = new GeometryAttribute.GeometryAttribute({
  329. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  330. componentsPerAttribute : 2,
  331. values : st
  332. });
  333. }
  334. if (vertexFormat.normal) {
  335. attributes.normal = new GeometryAttribute.GeometryAttribute({
  336. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  337. componentsPerAttribute : 3,
  338. values : attr.normals
  339. });
  340. }
  341. if (vertexFormat.tangent) {
  342. attributes.tangent = new GeometryAttribute.GeometryAttribute({
  343. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  344. componentsPerAttribute : 3,
  345. values : attr.tangents
  346. });
  347. }
  348. if (vertexFormat.bitangent) {
  349. attributes.bitangent = new GeometryAttribute.GeometryAttribute({
  350. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  351. componentsPerAttribute : 3,
  352. values : attr.bitangents
  353. });
  354. }
  355. return {
  356. attributes : attributes,
  357. indices : indices
  358. };
  359. }
  360. function extrudedAttributes(attributes, vertexFormat) {
  361. if (!vertexFormat.normal && !vertexFormat.tangent && !vertexFormat.bitangent && !vertexFormat.st) {
  362. return attributes;
  363. }
  364. var positions = attributes.position.values;
  365. var topNormals;
  366. var topBitangents;
  367. if (vertexFormat.normal || vertexFormat.bitangent) {
  368. topNormals = attributes.normal.values;
  369. topBitangents = attributes.bitangent.values;
  370. }
  371. var size = attributes.position.values.length / 18;
  372. var threeSize = size * 3;
  373. var twoSize = size * 2;
  374. var sixSize = threeSize * 2;
  375. var i;
  376. if (vertexFormat.normal || vertexFormat.bitangent || vertexFormat.tangent) {
  377. var normals = (vertexFormat.normal) ? new Float32Array(threeSize * 6) : undefined;
  378. var tangents = (vertexFormat.tangent) ? new Float32Array(threeSize * 6) : undefined;
  379. var bitangents = (vertexFormat.bitangent) ? new Float32Array(threeSize * 6) : undefined;
  380. var topPosition = cartesian1;
  381. var bottomPosition = cartesian2;
  382. var previousPosition = cartesian3;
  383. var normal = cartesian4;
  384. var tangent = cartesian5;
  385. var bitangent = cartesian6;
  386. var attrIndex = sixSize;
  387. for (i = 0; i < threeSize; i += 3) {
  388. var attrIndexOffset = attrIndex + sixSize;
  389. topPosition = Cartesian2.Cartesian3.fromArray(positions, i, topPosition);
  390. bottomPosition = Cartesian2.Cartesian3.fromArray(positions, i + threeSize, bottomPosition);
  391. previousPosition = Cartesian2.Cartesian3.fromArray(positions, (i + 3) % threeSize, previousPosition);
  392. bottomPosition = Cartesian2.Cartesian3.subtract(bottomPosition, topPosition, bottomPosition);
  393. previousPosition = Cartesian2.Cartesian3.subtract(previousPosition, topPosition, previousPosition);
  394. normal = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.cross(bottomPosition, previousPosition, normal), normal);
  395. if (vertexFormat.normal) {
  396. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset);
  397. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(normals, normal, attrIndexOffset + 3);
  398. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex);
  399. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(normals, normal, attrIndex + 3);
  400. }
  401. if (vertexFormat.tangent || vertexFormat.bitangent) {
  402. bitangent = Cartesian2.Cartesian3.fromArray(topNormals, i, bitangent);
  403. if (vertexFormat.bitangent) {
  404. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset);
  405. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndexOffset + 3);
  406. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex);
  407. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(bitangents, bitangent, attrIndex + 3);
  408. }
  409. if (vertexFormat.tangent) {
  410. tangent = Cartesian2.Cartesian3.normalize(Cartesian2.Cartesian3.cross(bitangent, normal, tangent), tangent);
  411. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset);
  412. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndexOffset + 3);
  413. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex);
  414. CorridorGeometryLibrary.CorridorGeometryLibrary.addAttribute(tangents, tangent, attrIndex + 3);
  415. }
  416. }
  417. attrIndex += 6;
  418. }
  419. if (vertexFormat.normal) {
  420. normals.set(topNormals); //top
  421. for (i = 0; i < threeSize; i += 3) { //bottom normals
  422. normals[i + threeSize] = -topNormals[i];
  423. normals[i + threeSize + 1] = -topNormals[i + 1];
  424. normals[i + threeSize + 2] = -topNormals[i + 2];
  425. }
  426. attributes.normal.values = normals;
  427. } else {
  428. attributes.normal = undefined;
  429. }
  430. if (vertexFormat.bitangent) {
  431. bitangents.set(topBitangents); //top
  432. bitangents.set(topBitangents, threeSize); //bottom
  433. attributes.bitangent.values = bitangents;
  434. } else {
  435. attributes.bitangent = undefined;
  436. }
  437. if (vertexFormat.tangent) {
  438. var topTangents = attributes.tangent.values;
  439. tangents.set(topTangents); //top
  440. tangents.set(topTangents, threeSize); //bottom
  441. attributes.tangent.values = tangents;
  442. }
  443. }
  444. if (vertexFormat.st) {
  445. var topSt = attributes.st.values;
  446. var st = new Float32Array(twoSize * 6);
  447. st.set(topSt); //top
  448. st.set(topSt, twoSize); //bottom
  449. var index = twoSize * 2;
  450. for ( var j = 0; j < 2; j++) {
  451. st[index++] = topSt[0];
  452. st[index++] = topSt[1];
  453. for (i = 2; i < twoSize; i += 2) {
  454. var s = topSt[i];
  455. var t = topSt[i + 1];
  456. st[index++] = s;
  457. st[index++] = t;
  458. st[index++] = s;
  459. st[index++] = t;
  460. }
  461. st[index++] = topSt[0];
  462. st[index++] = topSt[1];
  463. }
  464. attributes.st.values = st;
  465. }
  466. return attributes;
  467. }
  468. function addWallPositions(positions, index, wallPositions) {
  469. wallPositions[index++] = positions[0];
  470. wallPositions[index++] = positions[1];
  471. wallPositions[index++] = positions[2];
  472. for ( var i = 3; i < positions.length; i += 3) {
  473. var x = positions[i];
  474. var y = positions[i + 1];
  475. var z = positions[i + 2];
  476. wallPositions[index++] = x;
  477. wallPositions[index++] = y;
  478. wallPositions[index++] = z;
  479. wallPositions[index++] = x;
  480. wallPositions[index++] = y;
  481. wallPositions[index++] = z;
  482. }
  483. wallPositions[index++] = positions[0];
  484. wallPositions[index++] = positions[1];
  485. wallPositions[index++] = positions[2];
  486. return wallPositions;
  487. }
  488. function computePositionsExtruded(params, vertexFormat) {
  489. var topVertexFormat = new VertexFormat.VertexFormat({
  490. position : vertexFormat.position,
  491. normal : (vertexFormat.normal || vertexFormat.bitangent || params.shadowVolume),
  492. tangent : vertexFormat.tangent,
  493. bitangent : (vertexFormat.normal || vertexFormat.bitangent),
  494. st : vertexFormat.st
  495. });
  496. var ellipsoid = params.ellipsoid;
  497. var computedPositions = CorridorGeometryLibrary.CorridorGeometryLibrary.computePositions(params);
  498. var attr = combine(computedPositions, topVertexFormat, ellipsoid);
  499. var height = params.height;
  500. var extrudedHeight = params.extrudedHeight;
  501. var attributes = attr.attributes;
  502. var indices = attr.indices;
  503. var positions = attributes.position.values;
  504. var length = positions.length;
  505. var newPositions = new Float64Array(length * 6);
  506. var extrudedPositions = new Float64Array(length);
  507. extrudedPositions.set(positions);
  508. var wallPositions = new Float64Array(length * 4);
  509. positions = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(positions, height, ellipsoid);
  510. wallPositions = addWallPositions(positions, 0, wallPositions);
  511. extrudedPositions = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(extrudedPositions, extrudedHeight, ellipsoid);
  512. wallPositions = addWallPositions(extrudedPositions, length * 2, wallPositions);
  513. newPositions.set(positions);
  514. newPositions.set(extrudedPositions, length);
  515. newPositions.set(wallPositions, length * 2);
  516. attributes.position.values = newPositions;
  517. attributes = extrudedAttributes(attributes, vertexFormat);
  518. var i;
  519. var size = length / 3;
  520. if (params.shadowVolume) {
  521. var topNormals = attributes.normal.values;
  522. length = topNormals.length;
  523. var extrudeNormals = new Float32Array(length * 6);
  524. for (i = 0; i < length; i ++) {
  525. topNormals[i] = -topNormals[i];
  526. }
  527. //only get normals for bottom layer that's going to be pushed down
  528. extrudeNormals.set(topNormals, length); //bottom face
  529. extrudeNormals = addWallPositions(topNormals, length*4, extrudeNormals); //bottom wall
  530. attributes.extrudeDirection = new GeometryAttribute.GeometryAttribute({
  531. componentDatatype : ComponentDatatype.ComponentDatatype.FLOAT,
  532. componentsPerAttribute : 3,
  533. values : extrudeNormals
  534. });
  535. if (!vertexFormat.normal) {
  536. attributes.normal = undefined;
  537. }
  538. }
  539. if (defined.defined(params.offsetAttribute)) {
  540. var applyOffset = new Uint8Array(size * 6);
  541. if (params.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  542. applyOffset = GeometryOffsetAttribute.arrayFill(applyOffset, 1, 0, size); // top face
  543. applyOffset = GeometryOffsetAttribute.arrayFill(applyOffset, 1, size*2, size * 4); // top wall
  544. } else {
  545. var applyOffsetValue = params.offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  546. applyOffset = GeometryOffsetAttribute.arrayFill(applyOffset, applyOffsetValue);
  547. }
  548. attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  549. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  550. componentsPerAttribute : 1,
  551. values: applyOffset
  552. });
  553. }
  554. var iLength = indices.length;
  555. var twoSize = size + size;
  556. var newIndices = IndexDatatype.IndexDatatype.createTypedArray(newPositions.length / 3, iLength * 2 + twoSize * 3);
  557. newIndices.set(indices);
  558. var index = iLength;
  559. for (i = 0; i < iLength; i += 3) { // bottom indices
  560. var v0 = indices[i];
  561. var v1 = indices[i + 1];
  562. var v2 = indices[i + 2];
  563. newIndices[index++] = v2 + size;
  564. newIndices[index++] = v1 + size;
  565. newIndices[index++] = v0 + size;
  566. }
  567. var UL, LL, UR, LR;
  568. for (i = 0; i < twoSize; i += 2) { //wall indices
  569. UL = i + twoSize;
  570. LL = UL + twoSize;
  571. UR = UL + 1;
  572. LR = LL + 1;
  573. newIndices[index++] = UL;
  574. newIndices[index++] = LL;
  575. newIndices[index++] = UR;
  576. newIndices[index++] = UR;
  577. newIndices[index++] = LL;
  578. newIndices[index++] = LR;
  579. }
  580. return {
  581. attributes : attributes,
  582. indices : newIndices
  583. };
  584. }
  585. var scratchCartesian1 = new Cartesian2.Cartesian3();
  586. var scratchCartesian2 = new Cartesian2.Cartesian3();
  587. var scratchCartographic = new Cartesian2.Cartographic();
  588. function computeOffsetPoints(position1, position2, ellipsoid, halfWidth, min, max) {
  589. // Compute direction of offset the point
  590. var direction = Cartesian2.Cartesian3.subtract(position2, position1, scratchCartesian1);
  591. Cartesian2.Cartesian3.normalize(direction, direction);
  592. var normal = ellipsoid.geodeticSurfaceNormal(position1, scratchCartesian2);
  593. var offsetDirection = Cartesian2.Cartesian3.cross(direction, normal, scratchCartesian1);
  594. Cartesian2.Cartesian3.multiplyByScalar(offsetDirection, halfWidth, offsetDirection);
  595. var minLat = min.latitude;
  596. var minLon = min.longitude;
  597. var maxLat = max.latitude;
  598. var maxLon = max.longitude;
  599. // Compute 2 offset points
  600. Cartesian2.Cartesian3.add(position1, offsetDirection, scratchCartesian2);
  601. ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic);
  602. var lat = scratchCartographic.latitude;
  603. var lon = scratchCartographic.longitude;
  604. minLat = Math.min(minLat, lat);
  605. minLon = Math.min(minLon, lon);
  606. maxLat = Math.max(maxLat, lat);
  607. maxLon = Math.max(maxLon, lon);
  608. Cartesian2.Cartesian3.subtract(position1, offsetDirection, scratchCartesian2);
  609. ellipsoid.cartesianToCartographic(scratchCartesian2, scratchCartographic);
  610. lat = scratchCartographic.latitude;
  611. lon = scratchCartographic.longitude;
  612. minLat = Math.min(minLat, lat);
  613. minLon = Math.min(minLon, lon);
  614. maxLat = Math.max(maxLat, lat);
  615. maxLon = Math.max(maxLon, lon);
  616. min.latitude = minLat;
  617. min.longitude = minLon;
  618. max.latitude = maxLat;
  619. max.longitude = maxLon;
  620. }
  621. var scratchCartesianOffset = new Cartesian2.Cartesian3();
  622. var scratchCartesianEnds = new Cartesian2.Cartesian3();
  623. var scratchCartographicMin = new Cartesian2.Cartographic();
  624. var scratchCartographicMax = new Cartesian2.Cartographic();
  625. function computeRectangle(positions, ellipsoid, width, cornerType, result) {
  626. positions = scaleToSurface(positions, ellipsoid);
  627. var cleanPositions = arrayRemoveDuplicates.arrayRemoveDuplicates(positions, Cartesian2.Cartesian3.equalsEpsilon);
  628. var length = cleanPositions.length;
  629. if (length < 2 || width <= 0) {
  630. return new Cartesian2.Rectangle();
  631. }
  632. var halfWidth = width * 0.5;
  633. scratchCartographicMin.latitude = Number.POSITIVE_INFINITY;
  634. scratchCartographicMin.longitude = Number.POSITIVE_INFINITY;
  635. scratchCartographicMax.latitude = Number.NEGATIVE_INFINITY;
  636. scratchCartographicMax.longitude = Number.NEGATIVE_INFINITY;
  637. var lat, lon;
  638. if (cornerType === PolylineVolumeGeometryLibrary.CornerType.ROUNDED) {
  639. // Compute start cap
  640. var first = cleanPositions[0];
  641. Cartesian2.Cartesian3.subtract(first, cleanPositions[1], scratchCartesianOffset);
  642. Cartesian2.Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset);
  643. Cartesian2.Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset);
  644. Cartesian2.Cartesian3.add(first, scratchCartesianOffset, scratchCartesianEnds);
  645. ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic);
  646. lat = scratchCartographic.latitude;
  647. lon = scratchCartographic.longitude;
  648. scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat);
  649. scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon);
  650. scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat);
  651. scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon);
  652. }
  653. // Compute the rest
  654. for (var i = 0; i < length-1; ++i) {
  655. computeOffsetPoints(cleanPositions[i], cleanPositions[i+1], ellipsoid, halfWidth,
  656. scratchCartographicMin, scratchCartographicMax);
  657. }
  658. // Compute ending point
  659. var last = cleanPositions[length-1];
  660. Cartesian2.Cartesian3.subtract(last, cleanPositions[length-2], scratchCartesianOffset);
  661. Cartesian2.Cartesian3.normalize(scratchCartesianOffset, scratchCartesianOffset);
  662. Cartesian2.Cartesian3.multiplyByScalar(scratchCartesianOffset, halfWidth, scratchCartesianOffset);
  663. Cartesian2.Cartesian3.add(last, scratchCartesianOffset, scratchCartesianEnds);
  664. computeOffsetPoints(last, scratchCartesianEnds, ellipsoid, halfWidth,
  665. scratchCartographicMin, scratchCartographicMax);
  666. if (cornerType === PolylineVolumeGeometryLibrary.CornerType.ROUNDED) {
  667. // Compute end cap
  668. ellipsoid.cartesianToCartographic(scratchCartesianEnds, scratchCartographic);
  669. lat = scratchCartographic.latitude;
  670. lon = scratchCartographic.longitude;
  671. scratchCartographicMin.latitude = Math.min(scratchCartographicMin.latitude, lat);
  672. scratchCartographicMin.longitude = Math.min(scratchCartographicMin.longitude, lon);
  673. scratchCartographicMax.latitude = Math.max(scratchCartographicMax.latitude, lat);
  674. scratchCartographicMax.longitude = Math.max(scratchCartographicMax.longitude, lon);
  675. }
  676. var rectangle = defined.defined(result) ? result : new Cartesian2.Rectangle();
  677. rectangle.north = scratchCartographicMax.latitude;
  678. rectangle.south = scratchCartographicMin.latitude;
  679. rectangle.east = scratchCartographicMax.longitude;
  680. rectangle.west = scratchCartographicMin.longitude;
  681. return rectangle;
  682. }
  683. /**
  684. * A description of a corridor. Corridor geometry can be rendered with both {@link Primitive} and {@link GroundPrimitive}.
  685. *
  686. * @alias CorridorGeometry
  687. * @constructor
  688. *
  689. * @param {Object} options Object with the following properties:
  690. * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor.
  691. * @param {Number} options.width The distance between the edges of the corridor in meters.
  692. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  693. * @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.
  694. * @param {Number} [options.height=0] The distance in meters between the ellipsoid surface and the positions.
  695. * @param {Number} [options.extrudedHeight] The distance in meters between the ellipsoid surface and the extruded face.
  696. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  697. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners.
  698. *
  699. * @see CorridorGeometry.createGeometry
  700. * @see Packable
  701. *
  702. * @demo {@link https://sandcastle.cesium.com/index.html?src=Corridor.html|Cesium Sandcastle Corridor Demo}
  703. *
  704. * @example
  705. * var corridor = new Cesium.CorridorGeometry({
  706. * vertexFormat : Cesium.VertexFormat.POSITION_ONLY,
  707. * positions : Cesium.Cartesian3.fromDegreesArray([-72.0, 40.0, -70.0, 35.0]),
  708. * width : 100000
  709. * });
  710. */
  711. function CorridorGeometry(options) {
  712. options = defaultValue.defaultValue(options, defaultValue.defaultValue.EMPTY_OBJECT);
  713. var positions = options.positions;
  714. var width = options.width;
  715. //>>includeStart('debug', pragmas.debug);
  716. Check.Check.defined('options.positions', positions);
  717. Check.Check.defined('options.width', width);
  718. //>>includeEnd('debug');
  719. var height = defaultValue.defaultValue(options.height, 0.0);
  720. var extrudedHeight = defaultValue.defaultValue(options.extrudedHeight, height);
  721. this._positions = positions;
  722. this._ellipsoid = Cartesian2.Ellipsoid.clone(defaultValue.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84));
  723. this._vertexFormat = VertexFormat.VertexFormat.clone(defaultValue.defaultValue(options.vertexFormat, VertexFormat.VertexFormat.DEFAULT));
  724. this._width = width;
  725. this._height = Math.max(height, extrudedHeight);
  726. this._extrudedHeight = Math.min(height, extrudedHeight);
  727. this._cornerType = defaultValue.defaultValue(options.cornerType, PolylineVolumeGeometryLibrary.CornerType.ROUNDED);
  728. this._granularity = defaultValue.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  729. this._shadowVolume = defaultValue.defaultValue(options.shadowVolume, false);
  730. this._workerName = 'createCorridorGeometry';
  731. this._offsetAttribute = options.offsetAttribute;
  732. this._rectangle = undefined;
  733. /**
  734. * The number of elements used to pack the object into an array.
  735. * @type {Number}
  736. */
  737. this.packedLength = 1 + positions.length * Cartesian2.Cartesian3.packedLength + Cartesian2.Ellipsoid.packedLength + VertexFormat.VertexFormat.packedLength + 7;
  738. }
  739. /**
  740. * Stores the provided instance into the provided array.
  741. *
  742. * @param {CorridorGeometry} value The value to pack.
  743. * @param {Number[]} array The array to pack into.
  744. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  745. *
  746. * @returns {Number[]} The array that was packed into
  747. */
  748. CorridorGeometry.pack = function(value, array, startingIndex) {
  749. //>>includeStart('debug', pragmas.debug);
  750. Check.Check.defined('value', value);
  751. Check.Check.defined('array', array);
  752. //>>includeEnd('debug');
  753. startingIndex = defaultValue.defaultValue(startingIndex, 0);
  754. var positions = value._positions;
  755. var length = positions.length;
  756. array[startingIndex++] = length;
  757. for (var i = 0; i < length; ++i, startingIndex += Cartesian2.Cartesian3.packedLength) {
  758. Cartesian2.Cartesian3.pack(positions[i], array, startingIndex);
  759. }
  760. Cartesian2.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  761. startingIndex += Cartesian2.Ellipsoid.packedLength;
  762. VertexFormat.VertexFormat.pack(value._vertexFormat, array, startingIndex);
  763. startingIndex += VertexFormat.VertexFormat.packedLength;
  764. array[startingIndex++] = value._width;
  765. array[startingIndex++] = value._height;
  766. array[startingIndex++] = value._extrudedHeight;
  767. array[startingIndex++] = value._cornerType;
  768. array[startingIndex++] = value._granularity;
  769. array[startingIndex++] = value._shadowVolume ? 1.0 : 0.0;
  770. array[startingIndex] = defaultValue.defaultValue(value._offsetAttribute, -1);
  771. return array;
  772. };
  773. var scratchEllipsoid = Cartesian2.Ellipsoid.clone(Cartesian2.Ellipsoid.UNIT_SPHERE);
  774. var scratchVertexFormat = new VertexFormat.VertexFormat();
  775. var scratchOptions = {
  776. positions : undefined,
  777. ellipsoid : scratchEllipsoid,
  778. vertexFormat : scratchVertexFormat,
  779. width : undefined,
  780. height : undefined,
  781. extrudedHeight : undefined,
  782. cornerType : undefined,
  783. granularity : undefined,
  784. shadowVolume: undefined,
  785. offsetAttribute: undefined
  786. };
  787. /**
  788. * Retrieves an instance from a packed array.
  789. *
  790. * @param {Number[]} array The packed array.
  791. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  792. * @param {CorridorGeometry} [result] The object into which to store the result.
  793. * @returns {CorridorGeometry} The modified result parameter or a new CorridorGeometry instance if one was not provided.
  794. */
  795. CorridorGeometry.unpack = function(array, startingIndex, result) {
  796. //>>includeStart('debug', pragmas.debug);
  797. Check.Check.defined('array', array);
  798. //>>includeEnd('debug');
  799. startingIndex = defaultValue.defaultValue(startingIndex, 0);
  800. var length = array[startingIndex++];
  801. var positions = new Array(length);
  802. for (var i = 0; i < length; ++i, startingIndex += Cartesian2.Cartesian3.packedLength) {
  803. positions[i] = Cartesian2.Cartesian3.unpack(array, startingIndex);
  804. }
  805. var ellipsoid = Cartesian2.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  806. startingIndex += Cartesian2.Ellipsoid.packedLength;
  807. var vertexFormat = VertexFormat.VertexFormat.unpack(array, startingIndex, scratchVertexFormat);
  808. startingIndex += VertexFormat.VertexFormat.packedLength;
  809. var width = array[startingIndex++];
  810. var height = array[startingIndex++];
  811. var extrudedHeight = array[startingIndex++];
  812. var cornerType = array[startingIndex++];
  813. var granularity = array[startingIndex++];
  814. var shadowVolume = array[startingIndex++] === 1.0;
  815. var offsetAttribute = array[startingIndex];
  816. if (!defined.defined(result)) {
  817. scratchOptions.positions = positions;
  818. scratchOptions.width = width;
  819. scratchOptions.height = height;
  820. scratchOptions.extrudedHeight = extrudedHeight;
  821. scratchOptions.cornerType = cornerType;
  822. scratchOptions.granularity = granularity;
  823. scratchOptions.shadowVolume = shadowVolume;
  824. scratchOptions.offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  825. return new CorridorGeometry(scratchOptions);
  826. }
  827. result._positions = positions;
  828. result._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  829. result._vertexFormat = VertexFormat.VertexFormat.clone(vertexFormat, result._vertexFormat);
  830. result._width = width;
  831. result._height = height;
  832. result._extrudedHeight = extrudedHeight;
  833. result._cornerType = cornerType;
  834. result._granularity = granularity;
  835. result._shadowVolume = shadowVolume;
  836. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  837. return result;
  838. };
  839. /**
  840. * Computes the bounding rectangle given the provided options
  841. *
  842. * @param {Object} options Object with the following properties:
  843. * @param {Cartesian3[]} options.positions An array of positions that define the center of the corridor.
  844. * @param {Number} options.width The distance between the edges of the corridor in meters.
  845. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  846. * @param {CornerType} [options.cornerType=CornerType.ROUNDED] Determines the style of the corners.
  847. * @param {Rectangle} [result] An object in which to store the result.
  848. *
  849. * @returns {Rectangle} The result rectangle.
  850. */
  851. CorridorGeometry.computeRectangle = function(options, result) {
  852. options = defaultValue.defaultValue(options, defaultValue.defaultValue.EMPTY_OBJECT);
  853. var positions = options.positions;
  854. var width = options.width;
  855. //>>includeStart('debug', pragmas.debug);
  856. Check.Check.defined('options.positions', positions);
  857. Check.Check.defined('options.width', width);
  858. //>>includeEnd('debug');
  859. var ellipsoid = defaultValue.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  860. var cornerType = defaultValue.defaultValue(options.cornerType, PolylineVolumeGeometryLibrary.CornerType.ROUNDED);
  861. return computeRectangle(positions, ellipsoid, width, cornerType, result);
  862. };
  863. /**
  864. * Computes the geometric representation of a corridor, including its vertices, indices, and a bounding sphere.
  865. *
  866. * @param {CorridorGeometry} corridorGeometry A description of the corridor.
  867. * @returns {Geometry|undefined} The computed vertices and indices.
  868. */
  869. CorridorGeometry.createGeometry = function(corridorGeometry) {
  870. var positions = corridorGeometry._positions;
  871. var width = corridorGeometry._width;
  872. var ellipsoid = corridorGeometry._ellipsoid;
  873. positions = scaleToSurface(positions, ellipsoid);
  874. var cleanPositions = arrayRemoveDuplicates.arrayRemoveDuplicates(positions, Cartesian2.Cartesian3.equalsEpsilon);
  875. if ((cleanPositions.length < 2) || (width <= 0)) {
  876. return;
  877. }
  878. var height = corridorGeometry._height;
  879. var extrudedHeight = corridorGeometry._extrudedHeight;
  880. var extrude = !_Math.CesiumMath.equalsEpsilon(height, extrudedHeight, 0, _Math.CesiumMath.EPSILON2);
  881. var vertexFormat = corridorGeometry._vertexFormat;
  882. var params = {
  883. ellipsoid : ellipsoid,
  884. positions : cleanPositions,
  885. width : width,
  886. cornerType : corridorGeometry._cornerType,
  887. granularity : corridorGeometry._granularity,
  888. saveAttributes: true
  889. };
  890. var attr;
  891. if (extrude) {
  892. params.height = height;
  893. params.extrudedHeight = extrudedHeight;
  894. params.shadowVolume = corridorGeometry._shadowVolume;
  895. params.offsetAttribute = corridorGeometry._offsetAttribute;
  896. attr = computePositionsExtruded(params, vertexFormat);
  897. } else {
  898. var computedPositions = CorridorGeometryLibrary.CorridorGeometryLibrary.computePositions(params);
  899. attr = combine(computedPositions, vertexFormat, ellipsoid);
  900. attr.attributes.position.values = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(attr.attributes.position.values, height, ellipsoid);
  901. if (defined.defined(corridorGeometry._offsetAttribute)) {
  902. var applyOffsetValue = corridorGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  903. var length = attr.attributes.position.values.length;
  904. var applyOffset = new Uint8Array(length / 3);
  905. GeometryOffsetAttribute.arrayFill(applyOffset, applyOffsetValue);
  906. attr.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  907. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  908. componentsPerAttribute : 1,
  909. values: applyOffset
  910. });
  911. }
  912. }
  913. var attributes = attr.attributes;
  914. var boundingSphere = Transforms.BoundingSphere.fromVertices(attributes.position.values, undefined, 3);
  915. if (!vertexFormat.position) {
  916. attr.attributes.position.values = undefined;
  917. }
  918. return new GeometryAttribute.Geometry({
  919. attributes : attributes,
  920. indices : attr.indices,
  921. primitiveType : GeometryAttribute.PrimitiveType.TRIANGLES,
  922. boundingSphere : boundingSphere,
  923. offsetAttribute : corridorGeometry._offsetAttribute
  924. });
  925. };
  926. /**
  927. * @private
  928. */
  929. CorridorGeometry.createShadowVolume = function(corridorGeometry, minHeightFunc, maxHeightFunc) {
  930. var granularity = corridorGeometry._granularity;
  931. var ellipsoid = corridorGeometry._ellipsoid;
  932. var minHeight = minHeightFunc(granularity, ellipsoid);
  933. var maxHeight = maxHeightFunc(granularity, ellipsoid);
  934. return new CorridorGeometry({
  935. positions : corridorGeometry._positions,
  936. width : corridorGeometry._width,
  937. cornerType : corridorGeometry._cornerType,
  938. ellipsoid : ellipsoid,
  939. granularity : granularity,
  940. extrudedHeight : minHeight,
  941. height : maxHeight,
  942. vertexFormat : VertexFormat.VertexFormat.POSITION_ONLY,
  943. shadowVolume: true
  944. });
  945. };
  946. defineProperties.defineProperties(CorridorGeometry.prototype, {
  947. /**
  948. * @private
  949. */
  950. rectangle : {
  951. get : function() {
  952. if (!defined.defined(this._rectangle)) {
  953. this._rectangle = computeRectangle(this._positions, this._ellipsoid, this._width, this._cornerType);
  954. }
  955. return this._rectangle;
  956. }
  957. },
  958. /**
  959. * For remapping texture coordinates when rendering CorridorGeometries as GroundPrimitives.
  960. *
  961. * Corridors don't support stRotation,
  962. * so just return the corners of the original system.
  963. * @private
  964. */
  965. textureCoordinateRotationPoints : {
  966. get : function() {
  967. return [0, 0, 0, 1, 1, 0];
  968. }
  969. }
  970. });
  971. function createCorridorGeometry(corridorGeometry, offset) {
  972. if (defined.defined(offset)) {
  973. corridorGeometry = CorridorGeometry.unpack(corridorGeometry, offset);
  974. }
  975. corridorGeometry._ellipsoid = Cartesian2.Ellipsoid.clone(corridorGeometry._ellipsoid);
  976. return CorridorGeometry.createGeometry(corridorGeometry);
  977. }
  978. return createCorridorGeometry;
  979. });