PlaneGeometryUpdater.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import Cartesian2 from '../Core/Cartesian2.js';
  2. import Cartesian3 from '../Core/Cartesian3.js';
  3. import Check from '../Core/Check.js';
  4. import Color from '../Core/Color.js';
  5. import ColorGeometryInstanceAttribute from '../Core/ColorGeometryInstanceAttribute.js';
  6. import defined from '../Core/defined.js';
  7. import DeveloperError from '../Core/DeveloperError.js';
  8. import DistanceDisplayConditionGeometryInstanceAttribute from '../Core/DistanceDisplayConditionGeometryInstanceAttribute.js';
  9. import GeometryInstance from '../Core/GeometryInstance.js';
  10. import Iso8601 from '../Core/Iso8601.js';
  11. import CesiumMath from '../Core/Math.js';
  12. import Matrix3 from '../Core/Matrix3.js';
  13. import Matrix4 from '../Core/Matrix4.js';
  14. import PlaneGeometry from '../Core/PlaneGeometry.js';
  15. import PlaneOutlineGeometry from '../Core/PlaneOutlineGeometry.js';
  16. import Quaternion from '../Core/Quaternion.js';
  17. import ShowGeometryInstanceAttribute from '../Core/ShowGeometryInstanceAttribute.js';
  18. import MaterialAppearance from '../Scene/MaterialAppearance.js';
  19. import PerInstanceColorAppearance from '../Scene/PerInstanceColorAppearance.js';
  20. import ColorMaterialProperty from './ColorMaterialProperty.js';
  21. import DynamicGeometryUpdater from './DynamicGeometryUpdater.js';
  22. import GeometryUpdater from './GeometryUpdater.js';
  23. import Property from './Property.js';
  24. var positionScratch = new Cartesian3();
  25. var scratchColor = new Color();
  26. function PlaneGeometryOptions(entity) {
  27. this.id = entity;
  28. this.vertexFormat = undefined;
  29. this.plane = undefined;
  30. this.dimensions = undefined;
  31. }
  32. /**
  33. * A {@link GeometryUpdater} for planes.
  34. * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}.
  35. * @alias PlaneGeometryUpdater
  36. * @constructor
  37. *
  38. * @param {Entity} entity The entity containing the geometry to be visualized.
  39. * @param {Scene} scene The scene where visualization is taking place.
  40. */
  41. function PlaneGeometryUpdater(entity, scene) {
  42. GeometryUpdater.call(this, {
  43. entity : entity,
  44. scene : scene,
  45. geometryOptions : new PlaneGeometryOptions(entity),
  46. geometryPropertyName : 'plane',
  47. observedPropertyNames : ['availability', 'position', 'orientation', 'plane']
  48. });
  49. this._onEntityPropertyChanged(entity, 'plane', entity.plane, undefined);
  50. }
  51. if (defined(Object.create)) {
  52. PlaneGeometryUpdater.prototype = Object.create(GeometryUpdater.prototype);
  53. PlaneGeometryUpdater.prototype.constructor = PlaneGeometryUpdater;
  54. }
  55. /**
  56. * Creates the geometry instance which represents the fill of the geometry.
  57. *
  58. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  59. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry.
  60. *
  61. * @exception {DeveloperError} This instance does not represent a filled geometry.
  62. */
  63. PlaneGeometryUpdater.prototype.createFillGeometryInstance = function(time) {
  64. //>>includeStart('debug', pragmas.debug);
  65. Check.defined('time', time);
  66. if (!this._fillEnabled) {
  67. throw new DeveloperError('This instance does not represent a filled geometry.');
  68. }
  69. //>>includeEnd('debug');
  70. var entity = this._entity;
  71. var isAvailable = entity.isAvailable(time);
  72. var attributes;
  73. var color;
  74. var show = new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._fillProperty.getValue(time));
  75. var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
  76. var distanceDisplayConditionAttribute = DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition);
  77. if (this._materialProperty instanceof ColorMaterialProperty) {
  78. var currentColor;
  79. if (defined(this._materialProperty.color) && (this._materialProperty.color.isConstant || isAvailable)) {
  80. currentColor = this._materialProperty.color.getValue(time, scratchColor);
  81. }
  82. if (!defined(currentColor)) {
  83. currentColor = Color.WHITE;
  84. }
  85. color = ColorGeometryInstanceAttribute.fromColor(currentColor);
  86. attributes = {
  87. show : show,
  88. distanceDisplayCondition : distanceDisplayConditionAttribute,
  89. color : color
  90. };
  91. } else {
  92. attributes = {
  93. show : show,
  94. distanceDisplayCondition : distanceDisplayConditionAttribute
  95. };
  96. }
  97. var planeGraphics = entity.plane;
  98. var options = this._options;
  99. var modelMatrix = entity.computeModelMatrix(time);
  100. var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane);
  101. var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions);
  102. options.plane = plane;
  103. options.dimensions = dimensions;
  104. modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, this._scene.mapProjection.ellipsoid, modelMatrix);
  105. return new GeometryInstance({
  106. id : entity,
  107. geometry : new PlaneGeometry(this._options),
  108. modelMatrix : modelMatrix,
  109. attributes : attributes
  110. });
  111. };
  112. /**
  113. * Creates the geometry instance which represents the outline of the geometry.
  114. *
  115. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  116. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry.
  117. *
  118. * @exception {DeveloperError} This instance does not represent an outlined geometry.
  119. */
  120. PlaneGeometryUpdater.prototype.createOutlineGeometryInstance = function(time) {
  121. //>>includeStart('debug', pragmas.debug);
  122. Check.defined('time', time);
  123. if (!this._outlineEnabled) {
  124. throw new DeveloperError('This instance does not represent an outlined geometry.');
  125. }
  126. //>>includeEnd('debug');
  127. var entity = this._entity;
  128. var isAvailable = entity.isAvailable(time);
  129. var outlineColor = Property.getValueOrDefault(this._outlineColorProperty, time, Color.BLACK, scratchColor);
  130. var distanceDisplayCondition = this._distanceDisplayConditionProperty.getValue(time);
  131. var planeGraphics = entity.plane;
  132. var options = this._options;
  133. var modelMatrix = entity.computeModelMatrix(time);
  134. var plane = Property.getValueOrDefault(planeGraphics.plane, time, options.plane);
  135. var dimensions = Property.getValueOrUndefined(planeGraphics.dimensions, time, options.dimensions);
  136. options.plane = plane;
  137. options.dimensions = dimensions;
  138. modelMatrix = createPrimitiveMatrix(plane, dimensions, modelMatrix, this._scene.mapProjection.ellipsoid, modelMatrix);
  139. return new GeometryInstance({
  140. id : entity,
  141. geometry : new PlaneOutlineGeometry(),
  142. modelMatrix : modelMatrix,
  143. attributes : {
  144. show : new ShowGeometryInstanceAttribute(isAvailable && entity.isShowing && this._showProperty.getValue(time) && this._showOutlineProperty.getValue(time)),
  145. color : ColorGeometryInstanceAttribute.fromColor(outlineColor),
  146. distanceDisplayCondition : DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
  147. }
  148. });
  149. };
  150. PlaneGeometryUpdater.prototype._isHidden = function(entity, plane) {
  151. return !defined(plane.plane) || !defined(plane.dimensions) || !defined(entity.position) || GeometryUpdater.prototype._isHidden.call(this, entity, plane);
  152. };
  153. PlaneGeometryUpdater.prototype._getIsClosed = function(options) {
  154. return false;
  155. };
  156. PlaneGeometryUpdater.prototype._isDynamic = function(entity, plane) {
  157. return !entity.position.isConstant || //
  158. !Property.isConstant(entity.orientation) || //
  159. !plane.plane.isConstant || //
  160. !plane.dimensions.isConstant || //
  161. !Property.isConstant(plane.outlineWidth);
  162. };
  163. PlaneGeometryUpdater.prototype._setStaticOptions = function(entity, plane) {
  164. var isColorMaterial = this._materialProperty instanceof ColorMaterialProperty;
  165. var options = this._options;
  166. options.vertexFormat = isColorMaterial ? PerInstanceColorAppearance.VERTEX_FORMAT : MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
  167. options.plane = plane.plane.getValue(Iso8601.MINIMUM_VALUE, options.plane);
  168. options.dimensions = plane.dimensions.getValue(Iso8601.MINIMUM_VALUE, options.dimensions);
  169. };
  170. PlaneGeometryUpdater.DynamicGeometryUpdater = DynamicPlaneGeometryUpdater;
  171. /**
  172. * @private
  173. */
  174. function DynamicPlaneGeometryUpdater(geometryUpdater, primitives, groundPrimitives) {
  175. DynamicGeometryUpdater.call(this, geometryUpdater, primitives, groundPrimitives);
  176. }
  177. if (defined(Object.create)) {
  178. DynamicPlaneGeometryUpdater.prototype = Object.create(DynamicGeometryUpdater.prototype);
  179. DynamicPlaneGeometryUpdater.prototype.constructor = DynamicPlaneGeometryUpdater;
  180. }
  181. DynamicPlaneGeometryUpdater.prototype._isHidden = function(entity, plane, time) {
  182. var options = this._options;
  183. var position = Property.getValueOrUndefined(entity.position, time, positionScratch);
  184. return !defined(position) || !defined(options.plane) || !defined(options.dimensions) || DynamicGeometryUpdater.prototype._isHidden.call(this, entity, plane, time);
  185. };
  186. DynamicPlaneGeometryUpdater.prototype._setOptions = function(entity, plane, time) {
  187. var options = this._options;
  188. options.plane = Property.getValueOrDefault(plane.plane, time, options.plane);
  189. options.dimensions = Property.getValueOrUndefined(plane.dimensions, time, options.dimensions);
  190. };
  191. var scratchAxis = new Cartesian3();
  192. var scratchAxis2 = new Cartesian3();
  193. var scratchTranslation = new Cartesian3();
  194. var scratchNormal = new Cartesian3();
  195. var scratchScale = new Cartesian3();
  196. var scratchQuaternion = new Quaternion();
  197. var scratchMatrix3 = new Matrix3();
  198. function createPrimitiveMatrix(plane, dimensions, transform, ellipsoid, result) {
  199. var normal = plane.normal;
  200. var distance = plane.distance;
  201. var translation = Cartesian3.multiplyByScalar(normal, -distance, scratchTranslation);
  202. translation = Matrix4.multiplyByPoint(transform, translation, translation);
  203. var transformedNormal = Matrix4.multiplyByPointAsVector(transform, normal, scratchNormal);
  204. Cartesian3.normalize(transformedNormal, transformedNormal);
  205. var up = ellipsoid.geodeticSurfaceNormal(translation, scratchAxis2);
  206. if (CesiumMath.equalsEpsilon(Math.abs(Cartesian3.dot(up, transformedNormal)), 1.0, CesiumMath.EPSILON8)) {
  207. up = Cartesian3.clone(Cartesian3.UNIT_Z, up);
  208. }
  209. var left = Cartesian3.cross(up, transformedNormal, scratchAxis);
  210. up = Cartesian3.cross(transformedNormal, left, up);
  211. Cartesian3.normalize(left, left);
  212. Cartesian3.normalize(up, up);
  213. var rotationMatrix = scratchMatrix3;
  214. Matrix3.setColumn(rotationMatrix, 0, left, rotationMatrix);
  215. Matrix3.setColumn(rotationMatrix, 1, up, rotationMatrix);
  216. Matrix3.setColumn(rotationMatrix, 2, transformedNormal, rotationMatrix);
  217. var rotation = Quaternion.fromRotationMatrix(rotationMatrix, scratchQuaternion);
  218. var scale = Cartesian2.clone(dimensions, scratchScale);
  219. scale.z = 1.0;
  220. return Matrix4.fromTranslationQuaternionRotationScale(translation, rotation, scale, result);
  221. }
  222. /**
  223. * @private
  224. */
  225. PlaneGeometryUpdater.createPrimitiveMatrix = createPrimitiveMatrix;
  226. export default PlaneGeometryUpdater;