AttributeCompression-114c6354.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './when-e6985d2a', './Check-24cae389', './Math-392d0035', './Cartesian2-a5d6dde9'], function (exports, when, Check, _Math, Cartesian2) { 'use strict';
  3. var RIGHT_SHIFT = 1.0 / 256.0;
  4. var LEFT_SHIFT = 256.0;
  5. /**
  6. * Attribute compression and decompression functions.
  7. *
  8. * @namespace AttributeCompression
  9. *
  10. * @private
  11. */
  12. var AttributeCompression = {};
  13. /**
  14. * Encodes a normalized vector into 2 SNORM values in the range of [0-rangeMax] following the 'oct' encoding.
  15. *
  16. * Oct encoding is a compact representation of unit length vectors.
  17. * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors",
  18. * Cigolle et al 2014: {@link http://jcgt.org/published/0003/02/01/}
  19. *
  20. * @param {Cartesian3} vector The normalized vector to be compressed into 2 component 'oct' encoding.
  21. * @param {Cartesian2} result The 2 component oct-encoded unit length vector.
  22. * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
  23. * @returns {Cartesian2} The 2 component oct-encoded unit length vector.
  24. *
  25. * @exception {DeveloperError} vector must be normalized.
  26. *
  27. * @see AttributeCompression.octDecodeInRange
  28. */
  29. AttributeCompression.octEncodeInRange = function (vector, rangeMax, result) {
  30. //>>includeStart('debug', pragmas.debug);
  31. Check.Check.defined("vector", vector);
  32. Check.Check.defined("result", result);
  33. var magSquared = Cartesian2.Cartesian3.magnitudeSquared(vector);
  34. if (Math.abs(magSquared - 1.0) > _Math.CesiumMath.EPSILON6) {
  35. throw new Check.DeveloperError("vector must be normalized.");
  36. }
  37. //>>includeEnd('debug');
  38. result.x =
  39. vector.x / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
  40. result.y =
  41. vector.y / (Math.abs(vector.x) + Math.abs(vector.y) + Math.abs(vector.z));
  42. if (vector.z < 0) {
  43. var x = result.x;
  44. var y = result.y;
  45. result.x = (1.0 - Math.abs(y)) * _Math.CesiumMath.signNotZero(x);
  46. result.y = (1.0 - Math.abs(x)) * _Math.CesiumMath.signNotZero(y);
  47. }
  48. result.x = _Math.CesiumMath.toSNorm(result.x, rangeMax);
  49. result.y = _Math.CesiumMath.toSNorm(result.y, rangeMax);
  50. return result;
  51. };
  52. /**
  53. * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding.
  54. *
  55. * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
  56. * @param {Cartesian2} result The 2 byte oct-encoded unit length vector.
  57. * @returns {Cartesian2} The 2 byte oct-encoded unit length vector.
  58. *
  59. * @exception {DeveloperError} vector must be normalized.
  60. *
  61. * @see AttributeCompression.octEncodeInRange
  62. * @see AttributeCompression.octDecode
  63. */
  64. AttributeCompression.octEncode = function (vector, result) {
  65. return AttributeCompression.octEncodeInRange(vector, 255, result);
  66. };
  67. var octEncodeScratch = new Cartesian2.Cartesian2();
  68. var uint8ForceArray = new Uint8Array(1);
  69. function forceUint8(value) {
  70. uint8ForceArray[0] = value;
  71. return uint8ForceArray[0];
  72. }
  73. /**
  74. * @param {Cartesian3} vector The normalized vector to be compressed into 4 byte 'oct' encoding.
  75. * @param {Cartesian4} result The 4 byte oct-encoded unit length vector.
  76. * @returns {Cartesian4} The 4 byte oct-encoded unit length vector.
  77. *
  78. * @exception {DeveloperError} vector must be normalized.
  79. *
  80. * @see AttributeCompression.octEncodeInRange
  81. * @see AttributeCompression.octDecodeFromCartesian4
  82. */
  83. AttributeCompression.octEncodeToCartesian4 = function (vector, result) {
  84. AttributeCompression.octEncodeInRange(vector, 65535, octEncodeScratch);
  85. result.x = forceUint8(octEncodeScratch.x * RIGHT_SHIFT);
  86. result.y = forceUint8(octEncodeScratch.x);
  87. result.z = forceUint8(octEncodeScratch.y * RIGHT_SHIFT);
  88. result.w = forceUint8(octEncodeScratch.y);
  89. return result;
  90. };
  91. /**
  92. * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component vector.
  93. *
  94. * @param {Number} x The x component of the oct-encoded unit length vector.
  95. * @param {Number} y The y component of the oct-encoded unit length vector.
  96. * @param {Number} rangeMax The maximum value of the SNORM range. The encoded vector is stored in log2(rangeMax+1) bits.
  97. * @param {Cartesian3} result The decoded and normalized vector
  98. * @returns {Cartesian3} The decoded and normalized vector.
  99. *
  100. * @exception {DeveloperError} x and y must be unsigned normalized integers between 0 and rangeMax.
  101. *
  102. * @see AttributeCompression.octEncodeInRange
  103. */
  104. AttributeCompression.octDecodeInRange = function (x, y, rangeMax, result) {
  105. //>>includeStart('debug', pragmas.debug);
  106. Check.Check.defined("result", result);
  107. if (x < 0 || x > rangeMax || y < 0 || y > rangeMax) {
  108. throw new Check.DeveloperError(
  109. "x and y must be unsigned normalized integers between 0 and " + rangeMax
  110. );
  111. }
  112. //>>includeEnd('debug');
  113. result.x = _Math.CesiumMath.fromSNorm(x, rangeMax);
  114. result.y = _Math.CesiumMath.fromSNorm(y, rangeMax);
  115. result.z = 1.0 - (Math.abs(result.x) + Math.abs(result.y));
  116. if (result.z < 0.0) {
  117. var oldVX = result.x;
  118. result.x = (1.0 - Math.abs(result.y)) * _Math.CesiumMath.signNotZero(oldVX);
  119. result.y = (1.0 - Math.abs(oldVX)) * _Math.CesiumMath.signNotZero(result.y);
  120. }
  121. return Cartesian2.Cartesian3.normalize(result, result);
  122. };
  123. /**
  124. * Decodes a unit-length vector in 2 byte 'oct' encoding to a normalized 3-component vector.
  125. *
  126. * @param {Number} x The x component of the oct-encoded unit length vector.
  127. * @param {Number} y The y component of the oct-encoded unit length vector.
  128. * @param {Cartesian3} result The decoded and normalized vector.
  129. * @returns {Cartesian3} The decoded and normalized vector.
  130. *
  131. * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and 255.
  132. *
  133. * @see AttributeCompression.octDecodeInRange
  134. */
  135. AttributeCompression.octDecode = function (x, y, result) {
  136. return AttributeCompression.octDecodeInRange(x, y, 255, result);
  137. };
  138. /**
  139. * Decodes a unit-length vector in 4 byte 'oct' encoding to a normalized 3-component vector.
  140. *
  141. * @param {Cartesian4} encoded The oct-encoded unit length vector.
  142. * @param {Cartesian3} result The decoded and normalized vector.
  143. * @returns {Cartesian3} The decoded and normalized vector.
  144. *
  145. * @exception {DeveloperError} x, y, z, and w must be unsigned normalized integers between 0 and 255.
  146. *
  147. * @see AttributeCompression.octDecodeInRange
  148. * @see AttributeCompression.octEncodeToCartesian4
  149. */
  150. AttributeCompression.octDecodeFromCartesian4 = function (encoded, result) {
  151. //>>includeStart('debug', pragmas.debug);
  152. Check.Check.typeOf.object("encoded", encoded);
  153. Check.Check.typeOf.object("result", result);
  154. //>>includeEnd('debug');
  155. var x = encoded.x;
  156. var y = encoded.y;
  157. var z = encoded.z;
  158. var w = encoded.w;
  159. //>>includeStart('debug', pragmas.debug);
  160. if (
  161. x < 0 ||
  162. x > 255 ||
  163. y < 0 ||
  164. y > 255 ||
  165. z < 0 ||
  166. z > 255 ||
  167. w < 0 ||
  168. w > 255
  169. ) {
  170. throw new Check.DeveloperError(
  171. "x, y, z, and w must be unsigned normalized integers between 0 and 255"
  172. );
  173. }
  174. //>>includeEnd('debug');
  175. var xOct16 = x * LEFT_SHIFT + y;
  176. var yOct16 = z * LEFT_SHIFT + w;
  177. return AttributeCompression.octDecodeInRange(xOct16, yOct16, 65535, result);
  178. };
  179. /**
  180. * Packs an oct encoded vector into a single floating-point number.
  181. *
  182. * @param {Cartesian2} encoded The oct encoded vector.
  183. * @returns {Number} The oct encoded vector packed into a single float.
  184. *
  185. */
  186. AttributeCompression.octPackFloat = function (encoded) {
  187. //>>includeStart('debug', pragmas.debug);
  188. Check.Check.defined("encoded", encoded);
  189. //>>includeEnd('debug');
  190. return 256.0 * encoded.x + encoded.y;
  191. };
  192. var scratchEncodeCart2 = new Cartesian2.Cartesian2();
  193. /**
  194. * Encodes a normalized vector into 2 SNORM values in the range of [0-255] following the 'oct' encoding and
  195. * stores those values in a single float-point number.
  196. *
  197. * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding.
  198. * @returns {Number} The 2 byte oct-encoded unit length vector.
  199. *
  200. * @exception {DeveloperError} vector must be normalized.
  201. */
  202. AttributeCompression.octEncodeFloat = function (vector) {
  203. AttributeCompression.octEncode(vector, scratchEncodeCart2);
  204. return AttributeCompression.octPackFloat(scratchEncodeCart2);
  205. };
  206. /**
  207. * Decodes a unit-length vector in 'oct' encoding packed in a floating-point number to a normalized 3-component vector.
  208. *
  209. * @param {Number} value The oct-encoded unit length vector stored as a single floating-point number.
  210. * @param {Cartesian3} result The decoded and normalized vector
  211. * @returns {Cartesian3} The decoded and normalized vector.
  212. *
  213. */
  214. AttributeCompression.octDecodeFloat = function (value, result) {
  215. //>>includeStart('debug', pragmas.debug);
  216. Check.Check.defined("value", value);
  217. //>>includeEnd('debug');
  218. var temp = value / 256.0;
  219. var x = Math.floor(temp);
  220. var y = (temp - x) * 256.0;
  221. return AttributeCompression.octDecode(x, y, result);
  222. };
  223. /**
  224. * Encodes three normalized vectors into 6 SNORM values in the range of [0-255] following the 'oct' encoding and
  225. * packs those into two floating-point numbers.
  226. *
  227. * @param {Cartesian3} v1 A normalized vector to be compressed.
  228. * @param {Cartesian3} v2 A normalized vector to be compressed.
  229. * @param {Cartesian3} v3 A normalized vector to be compressed.
  230. * @param {Cartesian2} result The 'oct' encoded vectors packed into two floating-point numbers.
  231. * @returns {Cartesian2} The 'oct' encoded vectors packed into two floating-point numbers.
  232. *
  233. */
  234. AttributeCompression.octPack = function (v1, v2, v3, result) {
  235. //>>includeStart('debug', pragmas.debug);
  236. Check.Check.defined("v1", v1);
  237. Check.Check.defined("v2", v2);
  238. Check.Check.defined("v3", v3);
  239. Check.Check.defined("result", result);
  240. //>>includeEnd('debug');
  241. var encoded1 = AttributeCompression.octEncodeFloat(v1);
  242. var encoded2 = AttributeCompression.octEncodeFloat(v2);
  243. var encoded3 = AttributeCompression.octEncode(v3, scratchEncodeCart2);
  244. result.x = 65536.0 * encoded3.x + encoded1;
  245. result.y = 65536.0 * encoded3.y + encoded2;
  246. return result;
  247. };
  248. /**
  249. * Decodes three unit-length vectors in 'oct' encoding packed into a floating-point number to a normalized 3-component vector.
  250. *
  251. * @param {Cartesian2} packed The three oct-encoded unit length vectors stored as two floating-point number.
  252. * @param {Cartesian3} v1 One decoded and normalized vector.
  253. * @param {Cartesian3} v2 One decoded and normalized vector.
  254. * @param {Cartesian3} v3 One decoded and normalized vector.
  255. */
  256. AttributeCompression.octUnpack = function (packed, v1, v2, v3) {
  257. //>>includeStart('debug', pragmas.debug);
  258. Check.Check.defined("packed", packed);
  259. Check.Check.defined("v1", v1);
  260. Check.Check.defined("v2", v2);
  261. Check.Check.defined("v3", v3);
  262. //>>includeEnd('debug');
  263. var temp = packed.x / 65536.0;
  264. var x = Math.floor(temp);
  265. var encodedFloat1 = (temp - x) * 65536.0;
  266. temp = packed.y / 65536.0;
  267. var y = Math.floor(temp);
  268. var encodedFloat2 = (temp - y) * 65536.0;
  269. AttributeCompression.octDecodeFloat(encodedFloat1, v1);
  270. AttributeCompression.octDecodeFloat(encodedFloat2, v2);
  271. AttributeCompression.octDecode(x, y, v3);
  272. };
  273. /**
  274. * Pack texture coordinates into a single float. The texture coordinates will only preserve 12 bits of precision.
  275. *
  276. * @param {Cartesian2} textureCoordinates The texture coordinates to compress. Both coordinates must be in the range 0.0-1.0.
  277. * @returns {Number} The packed texture coordinates.
  278. *
  279. */
  280. AttributeCompression.compressTextureCoordinates = function (
  281. textureCoordinates
  282. ) {
  283. //>>includeStart('debug', pragmas.debug);
  284. Check.Check.defined("textureCoordinates", textureCoordinates);
  285. //>>includeEnd('debug');
  286. // Move x and y to the range 0-4095;
  287. var x = (textureCoordinates.x * 4095.0) | 0;
  288. var y = (textureCoordinates.y * 4095.0) | 0;
  289. return 4096.0 * x + y;
  290. };
  291. /**
  292. * Decompresses texture coordinates that were packed into a single float.
  293. *
  294. * @param {Number} compressed The compressed texture coordinates.
  295. * @param {Cartesian2} result The decompressed texture coordinates.
  296. * @returns {Cartesian2} The modified result parameter.
  297. *
  298. */
  299. AttributeCompression.decompressTextureCoordinates = function (
  300. compressed,
  301. result
  302. ) {
  303. //>>includeStart('debug', pragmas.debug);
  304. Check.Check.defined("compressed", compressed);
  305. Check.Check.defined("result", result);
  306. //>>includeEnd('debug');
  307. var temp = compressed / 4096.0;
  308. var xZeroTo4095 = Math.floor(temp);
  309. result.x = xZeroTo4095 / 4095.0;
  310. result.y = (compressed - xZeroTo4095 * 4096) / 4095;
  311. return result;
  312. };
  313. function zigZagDecode(value) {
  314. return (value >> 1) ^ -(value & 1);
  315. }
  316. /**
  317. * Decodes delta and ZigZag encoded vertices. This modifies the buffers in place.
  318. *
  319. * @param {Uint16Array} uBuffer The buffer view of u values.
  320. * @param {Uint16Array} vBuffer The buffer view of v values.
  321. * @param {Uint16Array} [heightBuffer] The buffer view of height values.
  322. *
  323. * @see {@link https://github.com/CesiumGS/quantized-mesh|quantized-mesh-1.0 terrain format}
  324. */
  325. AttributeCompression.zigZagDeltaDecode = function (
  326. uBuffer,
  327. vBuffer,
  328. heightBuffer
  329. ) {
  330. //>>includeStart('debug', pragmas.debug);
  331. Check.Check.defined("uBuffer", uBuffer);
  332. Check.Check.defined("vBuffer", vBuffer);
  333. Check.Check.typeOf.number.equals(
  334. "uBuffer.length",
  335. "vBuffer.length",
  336. uBuffer.length,
  337. vBuffer.length
  338. );
  339. if (when.defined(heightBuffer)) {
  340. Check.Check.typeOf.number.equals(
  341. "uBuffer.length",
  342. "heightBuffer.length",
  343. uBuffer.length,
  344. heightBuffer.length
  345. );
  346. }
  347. //>>includeEnd('debug');
  348. var count = uBuffer.length;
  349. var u = 0;
  350. var v = 0;
  351. var height = 0;
  352. for (var i = 0; i < count; ++i) {
  353. u += zigZagDecode(uBuffer[i]);
  354. v += zigZagDecode(vBuffer[i]);
  355. uBuffer[i] = u;
  356. vBuffer[i] = v;
  357. if (when.defined(heightBuffer)) {
  358. height += zigZagDecode(heightBuffer[i]);
  359. heightBuffer[i] = height;
  360. }
  361. }
  362. };
  363. exports.AttributeCompression = AttributeCompression;
  364. });