EncodedCartesian3.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import Cartesian3 from "./Cartesian3.js";
  2. import Check from "./Check.js";
  3. import defined from "./defined.js";
  4. /**
  5. * A fixed-point encoding of a {@link Cartesian3} with 64-bit floating-point components, as two {@link Cartesian3}
  6. * values that, when converted to 32-bit floating-point and added, approximate the original input.
  7. * <p>
  8. * This is used to encode positions in vertex buffers for rendering without jittering artifacts
  9. * as described in {@link http://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}.
  10. * </p>
  11. *
  12. * @alias EncodedCartesian3
  13. * @constructor
  14. *
  15. * @private
  16. */
  17. function EncodedCartesian3() {
  18. /**
  19. * The high bits for each component. Bits 0 to 22 store the whole value. Bits 23 to 31 are not used.
  20. *
  21. * @type {Cartesian3}
  22. * @default {@link Cartesian3.ZERO}
  23. */
  24. this.high = Cartesian3.clone(Cartesian3.ZERO);
  25. /**
  26. * The low bits for each component. Bits 7 to 22 store the whole value, and bits 0 to 6 store the fraction. Bits 23 to 31 are not used.
  27. *
  28. * @type {Cartesian3}
  29. * @default {@link Cartesian3.ZERO}
  30. */
  31. this.low = Cartesian3.clone(Cartesian3.ZERO);
  32. }
  33. /**
  34. * Encodes a 64-bit floating-point value as two floating-point values that, when converted to
  35. * 32-bit floating-point and added, approximate the original input. The returned object
  36. * has <code>high</code> and <code>low</code> properties for the high and low bits, respectively.
  37. * <p>
  38. * The fixed-point encoding follows {@link http://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}.
  39. * </p>
  40. *
  41. * @param {Number} value The floating-point value to encode.
  42. * @param {Object} [result] The object onto which to store the result.
  43. * @returns {Object} The modified result parameter or a new instance if one was not provided.
  44. *
  45. * @example
  46. * const value = 1234567.1234567;
  47. * const splitValue = Cesium.EncodedCartesian3.encode(value);
  48. */
  49. EncodedCartesian3.encode = function (value, result) {
  50. //>>includeStart('debug', pragmas.debug);
  51. Check.typeOf.number("value", value);
  52. //>>includeEnd('debug');
  53. if (!defined(result)) {
  54. result = {
  55. high: 0.0,
  56. low: 0.0,
  57. };
  58. }
  59. let doubleHigh;
  60. if (value >= 0.0) {
  61. doubleHigh = Math.floor(value / 65536.0) * 65536.0;
  62. result.high = doubleHigh;
  63. result.low = value - doubleHigh;
  64. } else {
  65. doubleHigh = Math.floor(-value / 65536.0) * 65536.0;
  66. result.high = -doubleHigh;
  67. result.low = value + doubleHigh;
  68. }
  69. return result;
  70. };
  71. const scratchEncode = {
  72. high: 0.0,
  73. low: 0.0,
  74. };
  75. /**
  76. * Encodes a {@link Cartesian3} with 64-bit floating-point components as two {@link Cartesian3}
  77. * values that, when converted to 32-bit floating-point and added, approximate the original input.
  78. * <p>
  79. * The fixed-point encoding follows {@link https://help.agi.com/AGIComponents/html/BlogPrecisionsPrecisions.htm|Precisions, Precisions}.
  80. * </p>
  81. *
  82. * @param {Cartesian3} cartesian The cartesian to encode.
  83. * @param {EncodedCartesian3} [result] The object onto which to store the result.
  84. * @returns {EncodedCartesian3} The modified result parameter or a new EncodedCartesian3 instance if one was not provided.
  85. *
  86. * @example
  87. * const cart = new Cesium.Cartesian3(-10000000.0, 0.0, 10000000.0);
  88. * const encoded = Cesium.EncodedCartesian3.fromCartesian(cart);
  89. */
  90. EncodedCartesian3.fromCartesian = function (cartesian, result) {
  91. //>>includeStart('debug', pragmas.debug);
  92. Check.typeOf.object("cartesian", cartesian);
  93. //>>includeEnd('debug');
  94. if (!defined(result)) {
  95. result = new EncodedCartesian3();
  96. }
  97. const high = result.high;
  98. const low = result.low;
  99. EncodedCartesian3.encode(cartesian.x, scratchEncode);
  100. high.x = scratchEncode.high;
  101. low.x = scratchEncode.low;
  102. EncodedCartesian3.encode(cartesian.y, scratchEncode);
  103. high.y = scratchEncode.high;
  104. low.y = scratchEncode.low;
  105. EncodedCartesian3.encode(cartesian.z, scratchEncode);
  106. high.z = scratchEncode.high;
  107. low.z = scratchEncode.low;
  108. return result;
  109. };
  110. const encodedP = new EncodedCartesian3();
  111. /**
  112. * Encodes the provided <code>cartesian</code>, and writes it to an array with <code>high</code>
  113. * components followed by <code>low</code> components, i.e. <code>[high.x, high.y, high.z, low.x, low.y, low.z]</code>.
  114. * <p>
  115. * This is used to create interleaved high-precision position vertex attributes.
  116. * </p>
  117. *
  118. * @param {Cartesian3} cartesian The cartesian to encode.
  119. * @param {Number[]} cartesianArray The array to write to.
  120. * @param {Number} index The index into the array to start writing. Six elements will be written.
  121. *
  122. * @exception {DeveloperError} index must be a number greater than or equal to 0.
  123. *
  124. * @example
  125. * const positions = [
  126. * new Cesium.Cartesian3(),
  127. * // ...
  128. * ];
  129. * const encodedPositions = new Float32Array(2 * 3 * positions.length);
  130. * let j = 0;
  131. * for (let i = 0; i < positions.length; ++i) {
  132. * Cesium.EncodedCartesian3.writeElement(positions[i], encodedPositions, j);
  133. * j += 6;
  134. * }
  135. */
  136. EncodedCartesian3.writeElements = function (cartesian, cartesianArray, index) {
  137. //>>includeStart('debug', pragmas.debug);
  138. Check.defined("cartesianArray", cartesianArray);
  139. Check.typeOf.number("index", index);
  140. Check.typeOf.number.greaterThanOrEquals("index", index, 0);
  141. //>>includeEnd('debug');
  142. EncodedCartesian3.fromCartesian(cartesian, encodedP);
  143. const high = encodedP.high;
  144. const low = encodedP.low;
  145. cartesianArray[index] = high.x;
  146. cartesianArray[index + 1] = high.y;
  147. cartesianArray[index + 2] = high.z;
  148. cartesianArray[index + 3] = low.x;
  149. cartesianArray[index + 4] = low.y;
  150. cartesianArray[index + 5] = low.z;
  151. };
  152. export default EncodedCartesian3;