FrustumOutlineGeometry.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import BoundingSphere from "./BoundingSphere.js";
  2. import Cartesian3 from "./Cartesian3.js";
  3. import Check from "./Check.js";
  4. import ComponentDatatype from "./ComponentDatatype.js";
  5. import defaultValue from "./defaultValue.js";
  6. import defined from "./defined.js";
  7. import FrustumGeometry from "./FrustumGeometry.js";
  8. import Geometry from "./Geometry.js";
  9. import GeometryAttribute from "./GeometryAttribute.js";
  10. import GeometryAttributes from "./GeometryAttributes.js";
  11. import OrthographicFrustum from "./OrthographicFrustum.js";
  12. import PerspectiveFrustum from "./PerspectiveFrustum.js";
  13. import PrimitiveType from "./PrimitiveType.js";
  14. import Quaternion from "./Quaternion.js";
  15. const PERSPECTIVE = 0;
  16. const ORTHOGRAPHIC = 1;
  17. /**
  18. * A description of the outline of a frustum with the given the origin and orientation.
  19. *
  20. * @alias FrustumOutlineGeometry
  21. * @constructor
  22. *
  23. * @param {object} options Object with the following properties:
  24. * @param {PerspectiveFrustum|OrthographicFrustum} options.frustum The frustum.
  25. * @param {Cartesian3} options.origin The origin of the frustum.
  26. * @param {Quaternion} options.orientation The orientation of the frustum.
  27. */
  28. function FrustumOutlineGeometry(options) {
  29. //>>includeStart('debug', pragmas.debug);
  30. Check.typeOf.object("options", options);
  31. Check.typeOf.object("options.frustum", options.frustum);
  32. Check.typeOf.object("options.origin", options.origin);
  33. Check.typeOf.object("options.orientation", options.orientation);
  34. //>>includeEnd('debug');
  35. const frustum = options.frustum;
  36. const orientation = options.orientation;
  37. const origin = options.origin;
  38. // This is private because it is used by DebugCameraPrimitive to draw a multi-frustum by
  39. // creating multiple FrustumOutlineGeometrys. This way the near plane of one frustum doesn't overlap
  40. // the far plane of another.
  41. const drawNearPlane = defaultValue(options._drawNearPlane, true);
  42. let frustumType;
  43. let frustumPackedLength;
  44. if (frustum instanceof PerspectiveFrustum) {
  45. frustumType = PERSPECTIVE;
  46. frustumPackedLength = PerspectiveFrustum.packedLength;
  47. } else if (frustum instanceof OrthographicFrustum) {
  48. frustumType = ORTHOGRAPHIC;
  49. frustumPackedLength = OrthographicFrustum.packedLength;
  50. }
  51. this._frustumType = frustumType;
  52. this._frustum = frustum.clone();
  53. this._origin = Cartesian3.clone(origin);
  54. this._orientation = Quaternion.clone(orientation);
  55. this._drawNearPlane = drawNearPlane;
  56. this._workerName = "createFrustumOutlineGeometry";
  57. /**
  58. * The number of elements used to pack the object into an array.
  59. * @type {number}
  60. */
  61. this.packedLength =
  62. 2 + frustumPackedLength + Cartesian3.packedLength + Quaternion.packedLength;
  63. }
  64. /**
  65. * Stores the provided instance into the provided array.
  66. *
  67. * @param {FrustumOutlineGeometry} value The value to pack.
  68. * @param {number[]} array The array to pack into.
  69. * @param {number} [startingIndex=0] The index into the array at which to start packing the elements.
  70. *
  71. * @returns {number[]} The array that was packed into
  72. */
  73. FrustumOutlineGeometry.pack = function (value, array, startingIndex) {
  74. //>>includeStart('debug', pragmas.debug);
  75. Check.typeOf.object("value", value);
  76. Check.defined("array", array);
  77. //>>includeEnd('debug');
  78. startingIndex = defaultValue(startingIndex, 0);
  79. const frustumType = value._frustumType;
  80. const frustum = value._frustum;
  81. array[startingIndex++] = frustumType;
  82. if (frustumType === PERSPECTIVE) {
  83. PerspectiveFrustum.pack(frustum, array, startingIndex);
  84. startingIndex += PerspectiveFrustum.packedLength;
  85. } else {
  86. OrthographicFrustum.pack(frustum, array, startingIndex);
  87. startingIndex += OrthographicFrustum.packedLength;
  88. }
  89. Cartesian3.pack(value._origin, array, startingIndex);
  90. startingIndex += Cartesian3.packedLength;
  91. Quaternion.pack(value._orientation, array, startingIndex);
  92. startingIndex += Quaternion.packedLength;
  93. array[startingIndex] = value._drawNearPlane ? 1.0 : 0.0;
  94. return array;
  95. };
  96. const scratchPackPerspective = new PerspectiveFrustum();
  97. const scratchPackOrthographic = new OrthographicFrustum();
  98. const scratchPackQuaternion = new Quaternion();
  99. const scratchPackorigin = new Cartesian3();
  100. /**
  101. * Retrieves an instance from a packed array.
  102. *
  103. * @param {number[]} array The packed array.
  104. * @param {number} [startingIndex=0] The starting index of the element to be unpacked.
  105. * @param {FrustumOutlineGeometry} [result] The object into which to store the result.
  106. */
  107. FrustumOutlineGeometry.unpack = function (array, startingIndex, result) {
  108. //>>includeStart('debug', pragmas.debug);
  109. Check.defined("array", array);
  110. //>>includeEnd('debug');
  111. startingIndex = defaultValue(startingIndex, 0);
  112. const frustumType = array[startingIndex++];
  113. let frustum;
  114. if (frustumType === PERSPECTIVE) {
  115. frustum = PerspectiveFrustum.unpack(
  116. array,
  117. startingIndex,
  118. scratchPackPerspective
  119. );
  120. startingIndex += PerspectiveFrustum.packedLength;
  121. } else {
  122. frustum = OrthographicFrustum.unpack(
  123. array,
  124. startingIndex,
  125. scratchPackOrthographic
  126. );
  127. startingIndex += OrthographicFrustum.packedLength;
  128. }
  129. const origin = Cartesian3.unpack(array, startingIndex, scratchPackorigin);
  130. startingIndex += Cartesian3.packedLength;
  131. const orientation = Quaternion.unpack(
  132. array,
  133. startingIndex,
  134. scratchPackQuaternion
  135. );
  136. startingIndex += Quaternion.packedLength;
  137. const drawNearPlane = array[startingIndex] === 1.0;
  138. if (!defined(result)) {
  139. return new FrustumOutlineGeometry({
  140. frustum: frustum,
  141. origin: origin,
  142. orientation: orientation,
  143. _drawNearPlane: drawNearPlane,
  144. });
  145. }
  146. const frustumResult =
  147. frustumType === result._frustumType ? result._frustum : undefined;
  148. result._frustum = frustum.clone(frustumResult);
  149. result._frustumType = frustumType;
  150. result._origin = Cartesian3.clone(origin, result._origin);
  151. result._orientation = Quaternion.clone(orientation, result._orientation);
  152. result._drawNearPlane = drawNearPlane;
  153. return result;
  154. };
  155. /**
  156. * Computes the geometric representation of a frustum outline, including its vertices, indices, and a bounding sphere.
  157. *
  158. * @param {FrustumOutlineGeometry} frustumGeometry A description of the frustum.
  159. * @returns {Geometry|undefined} The computed vertices and indices.
  160. */
  161. FrustumOutlineGeometry.createGeometry = function (frustumGeometry) {
  162. const frustumType = frustumGeometry._frustumType;
  163. const frustum = frustumGeometry._frustum;
  164. const origin = frustumGeometry._origin;
  165. const orientation = frustumGeometry._orientation;
  166. const drawNearPlane = frustumGeometry._drawNearPlane;
  167. const positions = new Float64Array(3 * 4 * 2);
  168. FrustumGeometry._computeNearFarPlanes(
  169. origin,
  170. orientation,
  171. frustumType,
  172. frustum,
  173. positions
  174. );
  175. const attributes = new GeometryAttributes({
  176. position: new GeometryAttribute({
  177. componentDatatype: ComponentDatatype.DOUBLE,
  178. componentsPerAttribute: 3,
  179. values: positions,
  180. }),
  181. });
  182. let offset;
  183. let index;
  184. const numberOfPlanes = drawNearPlane ? 2 : 1;
  185. const indices = new Uint16Array(8 * (numberOfPlanes + 1));
  186. // Build the near/far planes
  187. let i = drawNearPlane ? 0 : 1;
  188. for (; i < 2; ++i) {
  189. offset = drawNearPlane ? i * 8 : 0;
  190. index = i * 4;
  191. indices[offset] = index;
  192. indices[offset + 1] = index + 1;
  193. indices[offset + 2] = index + 1;
  194. indices[offset + 3] = index + 2;
  195. indices[offset + 4] = index + 2;
  196. indices[offset + 5] = index + 3;
  197. indices[offset + 6] = index + 3;
  198. indices[offset + 7] = index;
  199. }
  200. // Build the sides of the frustums
  201. for (i = 0; i < 2; ++i) {
  202. offset = (numberOfPlanes + i) * 8;
  203. index = i * 4;
  204. indices[offset] = index;
  205. indices[offset + 1] = index + 4;
  206. indices[offset + 2] = index + 1;
  207. indices[offset + 3] = index + 5;
  208. indices[offset + 4] = index + 2;
  209. indices[offset + 5] = index + 6;
  210. indices[offset + 6] = index + 3;
  211. indices[offset + 7] = index + 7;
  212. }
  213. return new Geometry({
  214. attributes: attributes,
  215. indices: indices,
  216. primitiveType: PrimitiveType.LINES,
  217. boundingSphere: BoundingSphere.fromVertices(positions),
  218. });
  219. };
  220. export default FrustumOutlineGeometry;