| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | import Cartesian3 from "../Core/Cartesian3.js";import Cartographic from "../Core/Cartographic.js";import Check from "../Core/Check.js";import defined from "../Core/defined.js";import destroyObject from "../Core/destroyObject.js";import Event from "../Core/Event.js";import Iso8601 from "../Core/Iso8601.js";import CesiumMath from "../Core/Math.js";import HeightReference from "../Scene/HeightReference.js";import SceneMode from "../Scene/SceneMode.js";import Property from "./Property.js";const scratchPosition = new Cartesian3();const scratchCarto = new Cartographic();/** * @private */function TerrainOffsetProperty(  scene,  positionProperty,  heightReferenceProperty,  extrudedHeightReferenceProperty) {  //>>includeStart('debug', pragmas.debug);  Check.defined("scene", scene);  Check.defined("positionProperty", positionProperty);  //>>includeEnd('debug');  this._scene = scene;  this._heightReference = heightReferenceProperty;  this._extrudedHeightReference = extrudedHeightReferenceProperty;  this._positionProperty = positionProperty;  this._position = new Cartesian3();  this._cartographicPosition = new Cartographic();  this._normal = new Cartesian3();  this._definitionChanged = new Event();  this._terrainHeight = 0;  this._removeCallbackFunc = undefined;  this._removeEventListener = undefined;  this._removeModeListener = undefined;  const that = this;  if (defined(scene.globe)) {    this._removeEventListener = scene.terrainProviderChanged.addEventListener(      function () {        that._updateClamping();      }    );    this._removeModeListener = scene.morphComplete.addEventListener(      function () {        that._updateClamping();      }    );  }  if (positionProperty.isConstant) {    const position = positionProperty.getValue(      Iso8601.MINIMUM_VALUE,      scratchPosition    );    if (      !defined(position) ||      Cartesian3.equals(position, Cartesian3.ZERO) ||      !defined(scene.globe)    ) {      return;    }    this._position = Cartesian3.clone(position, this._position);    this._updateClamping();    this._normal = scene.globe.ellipsoid.geodeticSurfaceNormal(      position,      this._normal    );  }}Object.defineProperties(TerrainOffsetProperty.prototype, {  /**   * Gets a value indicating if this property is constant.   * @memberof TerrainOffsetProperty.prototype   *   * @type {Boolean}   * @readonly   */  isConstant: {    get: function () {      return false;    },  },  /**   * Gets the event that is raised whenever the definition of this property changes.   * @memberof TerrainOffsetProperty.prototype   *   * @type {Event}   * @readonly   */  definitionChanged: {    get: function () {      return this._definitionChanged;    },  },});/** * @private */TerrainOffsetProperty.prototype._updateClamping = function () {  if (defined(this._removeCallbackFunc)) {    this._removeCallbackFunc();  }  const scene = this._scene;  const globe = scene.globe;  const position = this._position;  if (!defined(globe) || Cartesian3.equals(position, Cartesian3.ZERO)) {    this._terrainHeight = 0;    return;  }  const ellipsoid = globe.ellipsoid;  const surface = globe._surface;  const that = this;  const cartographicPosition = ellipsoid.cartesianToCartographic(    position,    this._cartographicPosition  );  const height = globe.getHeight(cartographicPosition);  if (defined(height)) {    this._terrainHeight = height;  } else {    this._terrainHeight = 0;  }  function updateFunction(clampedPosition) {    if (scene.mode === SceneMode.SCENE3D) {      const carto = ellipsoid.cartesianToCartographic(        clampedPosition,        scratchCarto      );      that._terrainHeight = carto.height;    } else {      that._terrainHeight = clampedPosition.x;    }    that.definitionChanged.raiseEvent();  }  this._removeCallbackFunc = surface.updateHeight(    cartographicPosition,    updateFunction  );};/** * Gets the height relative to the terrain based on the positions. * * @returns {Cartesian3} The offset */TerrainOffsetProperty.prototype.getValue = function (time, result) {  const heightReference = Property.getValueOrDefault(    this._heightReference,    time,    HeightReference.NONE  );  const extrudedHeightReference = Property.getValueOrDefault(    this._extrudedHeightReference,    time,    HeightReference.NONE  );  if (    heightReference === HeightReference.NONE &&    extrudedHeightReference !== HeightReference.RELATIVE_TO_GROUND  ) {    this._position = Cartesian3.clone(Cartesian3.ZERO, this._position);    return Cartesian3.clone(Cartesian3.ZERO, result);  }  if (this._positionProperty.isConstant) {    return Cartesian3.multiplyByScalar(      this._normal,      this._terrainHeight,      result    );  }  const scene = this._scene;  const position = this._positionProperty.getValue(time, scratchPosition);  if (    !defined(position) ||    Cartesian3.equals(position, Cartesian3.ZERO) ||    !defined(scene.globe)  ) {    return Cartesian3.clone(Cartesian3.ZERO, result);  }  if (    Cartesian3.equalsEpsilon(this._position, position, CesiumMath.EPSILON10)  ) {    return Cartesian3.multiplyByScalar(      this._normal,      this._terrainHeight,      result    );  }  this._position = Cartesian3.clone(position, this._position);  this._updateClamping();  const normal = scene.globe.ellipsoid.geodeticSurfaceNormal(    position,    this._normal  );  return Cartesian3.multiplyByScalar(normal, this._terrainHeight, result);};TerrainOffsetProperty.prototype.isDestroyed = function () {  return false;};TerrainOffsetProperty.prototype.destroy = function () {  if (defined(this._removeEventListener)) {    this._removeEventListener();  }  if (defined(this._removeModeListener)) {    this._removeModeListener();  }  if (defined(this._removeCallbackFunc)) {    this._removeCallbackFunc();  }  return destroyObject(this);};/** * A function which creates one or more providers. * @callback TerrainOffsetProperty.PositionFunction * @param {JulianDate} time The clock time at which to retrieve the position * @param {Cartesian3} result The result position * @returns {Cartesian3} The position at which to do the terrain height check */export default TerrainOffsetProperty;
 |