BoxGeometryUpdater.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. import BoxGeometry from "../Core/BoxGeometry.js";
  2. import BoxOutlineGeometry from "../Core/BoxOutlineGeometry.js";
  3. import Cartesian3 from "../Core/Cartesian3.js";
  4. import Check from "../Core/Check.js";
  5. import Color from "../Core/Color.js";
  6. import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
  7. import defined from "../Core/defined.js";
  8. import DeveloperError from "../Core/DeveloperError.js";
  9. import DistanceDisplayConditionGeometryInstanceAttribute from "../Core/DistanceDisplayConditionGeometryInstanceAttribute.js";
  10. import GeometryInstance from "../Core/GeometryInstance.js";
  11. import GeometryOffsetAttribute from "../Core/GeometryOffsetAttribute.js";
  12. import Iso8601 from "../Core/Iso8601.js";
  13. import OffsetGeometryInstanceAttribute from "../Core/OffsetGeometryInstanceAttribute.js";
  14. import ShowGeometryInstanceAttribute from "../Core/ShowGeometryInstanceAttribute.js";
  15. import HeightReference from "../Scene/HeightReference.js";
  16. import MaterialAppearance from "../Scene/MaterialAppearance.js";
  17. import PerInstanceColorAppearance from "../Scene/PerInstanceColorAppearance.js";
  18. import ColorMaterialProperty from "./ColorMaterialProperty.js";
  19. import DynamicGeometryUpdater from "./DynamicGeometryUpdater.js";
  20. import GeometryUpdater from "./GeometryUpdater.js";
  21. import heightReferenceOnEntityPropertyChanged from "./heightReferenceOnEntityPropertyChanged.js";
  22. import Property from "./Property.js";
  23. const defaultOffset = Cartesian3.ZERO;
  24. const offsetScratch = new Cartesian3();
  25. const positionScratch = new Cartesian3();
  26. const scratchColor = new Color();
  27. function BoxGeometryOptions(entity) {
  28. this.id = entity;
  29. this.vertexFormat = undefined;
  30. this.dimensions = undefined;
  31. this.offsetAttribute = undefined;
  32. }
  33. /**
  34. * A {@link GeometryUpdater} for boxes.
  35. * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}.
  36. * @alias BoxGeometryUpdater
  37. * @constructor
  38. *
  39. * @param {Entity} entity The entity containing the geometry to be visualized.
  40. * @param {Scene} scene The scene where visualization is taking place.
  41. */
  42. function BoxGeometryUpdater(entity, scene) {
  43. GeometryUpdater.call(this, {
  44. entity: entity,
  45. scene: scene,
  46. geometryOptions: new BoxGeometryOptions(entity),
  47. geometryPropertyName: "box",
  48. observedPropertyNames: ["availability", "position", "orientation", "box"],
  49. });
  50. this._onEntityPropertyChanged(entity, "box", entity.box, undefined);
  51. }
  52. if (defined(Object.create)) {
  53. BoxGeometryUpdater.prototype = Object.create(GeometryUpdater.prototype);
  54. BoxGeometryUpdater.prototype.constructor = BoxGeometryUpdater;
  55. }
  56. Object.defineProperties(BoxGeometryUpdater.prototype, {
  57. /**
  58. * Gets the terrain offset property
  59. * @type {TerrainOffsetProperty}
  60. * @memberof BoxGeometryUpdater.prototype
  61. * @readonly
  62. * @private
  63. */
  64. terrainOffsetProperty: {
  65. get: function () {
  66. return this._terrainOffsetProperty;
  67. },
  68. },
  69. });
  70. /**
  71. * Creates the geometry instance which represents the fill of the geometry.
  72. *
  73. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  74. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry.
  75. *
  76. * @exception {DeveloperError} This instance does not represent a filled geometry.
  77. */
  78. BoxGeometryUpdater.prototype.createFillGeometryInstance = function (time) {
  79. //>>includeStart('debug', pragmas.debug);
  80. Check.defined("time", time);
  81. if (!this._fillEnabled) {
  82. throw new DeveloperError(
  83. "This instance does not represent a filled geometry."
  84. );
  85. }
  86. //>>includeEnd('debug');
  87. const entity = this._entity;
  88. const isAvailable = entity.isAvailable(time);
  89. const show = new ShowGeometryInstanceAttribute(
  90. isAvailable &&
  91. entity.isShowing &&
  92. this._showProperty.getValue(time) &&
  93. this._fillProperty.getValue(time)
  94. );
  95. const distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(
  96. time
  97. );
  98. const distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  99. distanceDisplayCondition
  100. );
  101. const attributes = {
  102. show: show,
  103. distanceDisplayCondition: distanceDisplayConditionAttribute,
  104. color: undefined,
  105. offset: undefined,
  106. };
  107. if (this._materialProperty instanceof ColorMaterialProperty) {
  108. let currentColor;
  109. if (
  110. defined(this._materialProperty.color) &&
  111. (this._materialProperty.color.isConstant || isAvailable)
  112. ) {
  113. currentColor = this._materialProperty.color.getValue(time, scratchColor);
  114. }
  115. if (!defined(currentColor)) {
  116. currentColor = Color.WHITE;
  117. }
  118. attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
  119. }
  120. if (defined(this._options.offsetAttribute)) {
  121. attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(
  122. Property.getValueOrDefault(
  123. this._terrainOffsetProperty,
  124. time,
  125. defaultOffset,
  126. offsetScratch
  127. )
  128. );
  129. }
  130. return new GeometryInstance({
  131. id: entity,
  132. geometry: BoxGeometry.fromDimensions(this._options),
  133. modelMatrix: entity.computeModelMatrixForHeightReference(
  134. time,
  135. entity.box.heightReference,
  136. this._options.dimensions.z * 0.5,
  137. this._scene.mapProjection.ellipsoid
  138. ),
  139. attributes: attributes,
  140. });
  141. };
  142. /**
  143. * Creates the geometry instance which represents the outline of the geometry.
  144. *
  145. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  146. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry.
  147. *
  148. * @exception {DeveloperError} This instance does not represent an outlined geometry.
  149. */
  150. BoxGeometryUpdater.prototype.createOutlineGeometryInstance = function (time) {
  151. //>>includeStart('debug', pragmas.debug);
  152. Check.defined("time", time);
  153. if (!this._outlineEnabled) {
  154. throw new DeveloperError(
  155. "This instance does not represent an outlined geometry."
  156. );
  157. }
  158. //>>includeEnd('debug');
  159. const entity = this._entity;
  160. const isAvailable = entity.isAvailable(time);
  161. const outlineColor = Property.getValueOrDefault(
  162. this._outlineColorProperty,
  163. time,
  164. Color.BLACK,
  165. scratchColor
  166. );
  167. const distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(
  168. time
  169. );
  170. const attributes = {
  171. show: new ShowGeometryInstanceAttribute(
  172. isAvailable &&
  173. entity.isShowing &&
  174. this._showProperty.getValue(time) &&
  175. this._showOutlineProperty.getValue(time)
  176. ),
  177. color: ColorGeometryInstanceAttribute.fromColor(outlineColor),
  178. distanceDisplayCondition: DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  179. distanceDisplayCondition
  180. ),
  181. offset: undefined,
  182. };
  183. if (defined(this._options.offsetAttribute)) {
  184. attributes.offset = OffsetGeometryInstanceAttribute.fromCartesian3(
  185. Property.getValueOrDefault(
  186. this._terrainOffsetProperty,
  187. time,
  188. defaultOffset,
  189. offsetScratch
  190. )
  191. );
  192. }
  193. return new GeometryInstance({
  194. id: entity,
  195. geometry: BoxOutlineGeometry.fromDimensions(this._options),
  196. modelMatrix: entity.computeModelMatrixForHeightReference(
  197. time,
  198. entity.box.heightReference,
  199. this._options.dimensions.z * 0.5,
  200. this._scene.mapProjection.ellipsoid
  201. ),
  202. attributes: attributes,
  203. });
  204. };
  205. BoxGeometryUpdater.prototype._computeCenter = function (time, result) {
  206. return Property.getValueOrUndefined(this._entity.position, time, result);
  207. };
  208. BoxGeometryUpdater.prototype._isHidden = function (entity, box) {
  209. return (
  210. !defined(box.dimensions) ||
  211. !defined(entity.position) ||
  212. GeometryUpdater.prototype._isHidden.call(this, entity, box)
  213. );
  214. };
  215. BoxGeometryUpdater.prototype._isDynamic = function (entity, box) {
  216. return (
  217. !entity.position.isConstant ||
  218. !Property.isConstant(entity.orientation) ||
  219. !box.dimensions.isConstant ||
  220. !Property.isConstant(box.outlineWidth)
  221. );
  222. };
  223. BoxGeometryUpdater.prototype._setStaticOptions = function (entity, box) {
  224. const heightReference = Property.getValueOrDefault(
  225. box.heightReference,
  226. Iso8601.MINIMUM_VALUE,
  227. HeightReference.NONE
  228. );
  229. const options = this._options;
  230. options.vertexFormat =
  231. this._materialProperty instanceof ColorMaterialProperty
  232. ? PerInstanceColorAppearance.VERTEX_FORMAT
  233. : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
  234. options.dimensions = box.dimensions.getValue(
  235. Iso8601.MINIMUM_VALUE,
  236. options.dimensions
  237. );
  238. options.offsetAttribute =
  239. heightReference !== HeightReference.NONE
  240. ? GeometryOffsetAttribute.ALL
  241. : undefined;
  242. };
  243. BoxGeometryUpdater.prototype._onEntityPropertyChanged = heightReferenceOnEntityPropertyChanged;
  244. BoxGeometryUpdater.DynamicGeometryUpdater = DynamicBoxGeometryUpdater;
  245. /**
  246. * @private
  247. */
  248. function DynamicBoxGeometryUpdater(
  249. geometryUpdater,
  250. primitives,
  251. groundPrimitives
  252. ) {
  253. DynamicGeometryUpdater.call(
  254. this,
  255. geometryUpdater,
  256. primitives,
  257. groundPrimitives
  258. );
  259. }
  260. if (defined(Object.create)) {
  261. DynamicBoxGeometryUpdater.prototype = Object.create(
  262. DynamicGeometryUpdater.prototype
  263. );
  264. DynamicBoxGeometryUpdater.prototype.constructor = DynamicBoxGeometryUpdater;
  265. }
  266. DynamicBoxGeometryUpdater.prototype._isHidden = function (entity, box, time) {
  267. const position = Property.getValueOrUndefined(
  268. entity.position,
  269. time,
  270. positionScratch
  271. );
  272. const dimensions = this._options.dimensions;
  273. return (
  274. !defined(position) ||
  275. !defined(dimensions) ||
  276. DynamicGeometryUpdater.prototype._isHidden.call(this, entity, box, time)
  277. );
  278. };
  279. DynamicBoxGeometryUpdater.prototype._setOptions = function (entity, box, time) {
  280. const heightReference = Property.getValueOrDefault(
  281. box.heightReference,
  282. time,
  283. HeightReference.NONE
  284. );
  285. const options = this._options;
  286. options.dimensions = Property.getValueOrUndefined(
  287. box.dimensions,
  288. time,
  289. options.dimensions
  290. );
  291. options.offsetAttribute =
  292. heightReference !== HeightReference.NONE
  293. ? GeometryOffsetAttribute.ALL
  294. : undefined;
  295. };
  296. export default BoxGeometryUpdater;