Entity.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. import Cartesian3 from '../Core/Cartesian3.js';
  2. import Cartographic from '../Core/Cartographic.js';
  3. import Check from '../Core/Check.js';
  4. import createGuid from '../Core/createGuid.js';
  5. import defaultValue from '../Core/defaultValue.js';
  6. import defined from '../Core/defined.js';
  7. import defineProperties from '../Core/defineProperties.js';
  8. import DeveloperError from '../Core/DeveloperError.js';
  9. import Event from '../Core/Event.js';
  10. import CesiumMath from '../Core/Math.js';
  11. import Matrix3 from '../Core/Matrix3.js';
  12. import Matrix4 from '../Core/Matrix4.js';
  13. import Quaternion from '../Core/Quaternion.js';
  14. import Transforms from '../Core/Transforms.js';
  15. import GroundPolylinePrimitive from '../Scene/GroundPolylinePrimitive.js';
  16. import GroundPrimitive from '../Scene/GroundPrimitive.js';
  17. import HeightReference from '../Scene/HeightReference.js';
  18. import BillboardGraphics from './BillboardGraphics.js';
  19. import BoxGraphics from './BoxGraphics.js';
  20. import ConstantPositionProperty from './ConstantPositionProperty.js';
  21. import CorridorGraphics from './CorridorGraphics.js';
  22. import createPropertyDescriptor from './createPropertyDescriptor.js';
  23. import createRawPropertyDescriptor from './createRawPropertyDescriptor.js';
  24. import CylinderGraphics from './CylinderGraphics.js';
  25. import EllipseGraphics from './EllipseGraphics.js';
  26. import EllipsoidGraphics from './EllipsoidGraphics.js';
  27. import LabelGraphics from './LabelGraphics.js';
  28. import ModelGraphics from './ModelGraphics.js';
  29. import PathGraphics from './PathGraphics.js';
  30. import PlaneGraphics from './PlaneGraphics.js';
  31. import PointGraphics from './PointGraphics.js';
  32. import PolygonGraphics from './PolygonGraphics.js';
  33. import PolylineGraphics from './PolylineGraphics.js';
  34. import PolylineVolumeGraphics from './PolylineVolumeGraphics.js';
  35. import Property from './Property.js';
  36. import PropertyBag from './PropertyBag.js';
  37. import RectangleGraphics from './RectangleGraphics.js';
  38. import WallGraphics from './WallGraphics.js';
  39. var cartoScratch = new Cartographic();
  40. function createConstantPositionProperty(value) {
  41. return new ConstantPositionProperty(value);
  42. }
  43. function createPositionPropertyDescriptor(name) {
  44. return createPropertyDescriptor(name, undefined, createConstantPositionProperty);
  45. }
  46. function createPropertyTypeDescriptor(name, Type) {
  47. return createPropertyDescriptor(name, undefined, function(value) {
  48. if (value instanceof Type) {
  49. return value;
  50. }
  51. return new Type(value);
  52. });
  53. }
  54. /**
  55. * Entity instances aggregate multiple forms of visualization into a single high-level object.
  56. * They can be created manually and added to {@link Viewer#entities} or be produced by
  57. * data sources, such as {@link CzmlDataSource} and {@link GeoJsonDataSource}.
  58. * @alias Entity
  59. * @constructor
  60. *
  61. * @param {Object} [options] Object with the following properties:
  62. * @param {String} [options.id] A unique identifier for this object. If none is provided, a GUID is generated.
  63. * @param {String} [options.name] A human readable name to display to users. It does not have to be unique.
  64. * @param {TimeIntervalCollection} [options.availability] The availability, if any, associated with this object.
  65. * @param {Boolean} [options.show] A boolean value indicating if the entity and its children are displayed.
  66. * @param {Property} [options.description] A string Property specifying an HTML description for this entity.
  67. * @param {PositionProperty} [options.position] A Property specifying the entity position.
  68. * @param {Property} [options.orientation] A Property specifying the entity orientation.
  69. * @param {Property} [options.viewFrom] A suggested initial offset for viewing this object.
  70. * @param {Entity} [options.parent] A parent entity to associate with this entity.
  71. * @param {BillboardGraphics} [options.billboard] A billboard to associate with this entity.
  72. * @param {BoxGraphics} [options.box] A box to associate with this entity.
  73. * @param {CorridorGraphics} [options.corridor] A corridor to associate with this entity.
  74. * @param {CylinderGraphics} [options.cylinder] A cylinder to associate with this entity.
  75. * @param {EllipseGraphics} [options.ellipse] A ellipse to associate with this entity.
  76. * @param {EllipsoidGraphics} [options.ellipsoid] A ellipsoid to associate with this entity.
  77. * @param {LabelGraphics} [options.label] A options.label to associate with this entity.
  78. * @param {ModelGraphics} [options.model] A model to associate with this entity.
  79. * @param {PathGraphics} [options.path] A path to associate with this entity.
  80. * @param {PlaneGraphics} [options.plane] A plane to associate with this entity.
  81. * @param {PointGraphics} [options.point] A point to associate with this entity.
  82. * @param {PolygonGraphics} [options.polygon] A polygon to associate with this entity.
  83. * @param {PolylineGraphics} [options.polyline] A polyline to associate with this entity.
  84. * @param {PropertyBag} [options.properties] Arbitrary properties to associate with this entity.
  85. * @param {PolylineVolumeGraphics} [options.polylineVolume] A polylineVolume to associate with this entity.
  86. * @param {RectangleGraphics} [options.rectangle] A rectangle to associate with this entity.
  87. * @param {WallGraphics} [options.wall] A wall to associate with this entity.
  88. *
  89. * @see {@link https://cesium.com/docs/tutorials/creating-entities/|Creating Entities}
  90. */
  91. function Entity(options) {
  92. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  93. var id = options.id;
  94. if (!defined(id)) {
  95. id = createGuid();
  96. }
  97. this._availability = undefined;
  98. this._id = id;
  99. this._definitionChanged = new Event();
  100. this._name = options.name;
  101. this._show = defaultValue(options.show, true);
  102. this._parent = undefined;
  103. this._propertyNames = ['billboard', 'box', 'corridor', 'cylinder', 'description', 'ellipse', //
  104. 'ellipsoid', 'label', 'model', 'orientation', 'path', 'plane', 'point', 'polygon', //
  105. 'polyline', 'polylineVolume', 'position', 'properties', 'rectangle', 'viewFrom', 'wall'];
  106. this._billboard = undefined;
  107. this._billboardSubscription = undefined;
  108. this._box = undefined;
  109. this._boxSubscription = undefined;
  110. this._corridor = undefined;
  111. this._corridorSubscription = undefined;
  112. this._cylinder = undefined;
  113. this._cylinderSubscription = undefined;
  114. this._description = undefined;
  115. this._descriptionSubscription = undefined;
  116. this._ellipse = undefined;
  117. this._ellipseSubscription = undefined;
  118. this._ellipsoid = undefined;
  119. this._ellipsoidSubscription = undefined;
  120. this._label = undefined;
  121. this._labelSubscription = undefined;
  122. this._model = undefined;
  123. this._modelSubscription = undefined;
  124. this._orientation = undefined;
  125. this._orientationSubscription = undefined;
  126. this._path = undefined;
  127. this._pathSubscription = undefined;
  128. this._plane = undefined;
  129. this._planeSubscription = undefined;
  130. this._point = undefined;
  131. this._pointSubscription = undefined;
  132. this._polygon = undefined;
  133. this._polygonSubscription = undefined;
  134. this._polyline = undefined;
  135. this._polylineSubscription = undefined;
  136. this._polylineVolume = undefined;
  137. this._polylineVolumeSubscription = undefined;
  138. this._position = undefined;
  139. this._positionSubscription = undefined;
  140. this._properties = undefined;
  141. this._propertiesSubscription = undefined;
  142. this._rectangle = undefined;
  143. this._rectangleSubscription = undefined;
  144. this._viewFrom = undefined;
  145. this._viewFromSubscription = undefined;
  146. this._wall = undefined;
  147. this._wallSubscription = undefined;
  148. this._children = [];
  149. /**
  150. * Gets or sets the entity collection that this entity belongs to.
  151. * @type {EntityCollection}
  152. */
  153. this.entityCollection = undefined;
  154. this.parent = options.parent;
  155. this.merge(options);
  156. }
  157. function updateShow(entity, children, isShowing) {
  158. var length = children.length;
  159. for (var i = 0; i < length; i++) {
  160. var child = children[i];
  161. var childShow = child._show;
  162. var oldValue = !isShowing && childShow;
  163. var newValue = isShowing && childShow;
  164. if (oldValue !== newValue) {
  165. updateShow(child, child._children, isShowing);
  166. }
  167. }
  168. entity._definitionChanged.raiseEvent(entity, 'isShowing', isShowing, !isShowing);
  169. }
  170. defineProperties(Entity.prototype, {
  171. /**
  172. * The availability, if any, associated with this object.
  173. * If availability is undefined, it is assumed that this object's
  174. * other properties will return valid data for any provided time.
  175. * If availability exists, the objects other properties will only
  176. * provide valid data if queried within the given interval.
  177. * @memberof Entity.prototype
  178. * @type {TimeIntervalCollection}
  179. */
  180. availability : createRawPropertyDescriptor('availability'),
  181. /**
  182. * Gets the unique ID associated with this object.
  183. * @memberof Entity.prototype
  184. * @type {String}
  185. */
  186. id : {
  187. get : function() {
  188. return this._id;
  189. }
  190. },
  191. /**
  192. * Gets the event that is raised whenever a property or sub-property is changed or modified.
  193. * @memberof Entity.prototype
  194. *
  195. * @type {Event}
  196. * @readonly
  197. */
  198. definitionChanged : {
  199. get : function() {
  200. return this._definitionChanged;
  201. }
  202. },
  203. /**
  204. * Gets or sets the name of the object. The name is intended for end-user
  205. * consumption and does not need to be unique.
  206. * @memberof Entity.prototype
  207. * @type {String}
  208. */
  209. name : createRawPropertyDescriptor('name'),
  210. /**
  211. * Gets or sets whether this entity should be displayed. When set to true,
  212. * the entity is only displayed if the parent entity's show property is also true.
  213. * @memberof Entity.prototype
  214. * @type {Boolean}
  215. */
  216. show : {
  217. get : function() {
  218. return this._show;
  219. },
  220. set : function(value) {
  221. //>>includeStart('debug', pragmas.debug);
  222. if (!defined(value)) {
  223. throw new DeveloperError('value is required.');
  224. }
  225. //>>includeEnd('debug');
  226. if (value === this._show) {
  227. return;
  228. }
  229. var wasShowing = this.isShowing;
  230. this._show = value;
  231. var isShowing = this.isShowing;
  232. if (wasShowing !== isShowing) {
  233. updateShow(this, this._children, isShowing);
  234. }
  235. this._definitionChanged.raiseEvent(this, 'show', value, !value);
  236. }
  237. },
  238. /**
  239. * Gets whether this entity is being displayed, taking into account
  240. * the visibility of any ancestor entities.
  241. * @memberof Entity.prototype
  242. * @type {Boolean}
  243. */
  244. isShowing : {
  245. get : function() {
  246. return this._show && (!defined(this.entityCollection) || this.entityCollection.show) && (!defined(this._parent) || this._parent.isShowing);
  247. }
  248. },
  249. /**
  250. * Gets or sets the parent object.
  251. * @memberof Entity.prototype
  252. * @type {Entity}
  253. */
  254. parent : {
  255. get : function() {
  256. return this._parent;
  257. },
  258. set : function(value) {
  259. var oldValue = this._parent;
  260. if (oldValue === value) {
  261. return;
  262. }
  263. var wasShowing = this.isShowing;
  264. if (defined(oldValue)) {
  265. var index = oldValue._children.indexOf(this);
  266. oldValue._children.splice(index, 1);
  267. }
  268. this._parent = value;
  269. if (defined(value)) {
  270. value._children.push(this);
  271. }
  272. var isShowing = this.isShowing;
  273. if (wasShowing !== isShowing) {
  274. updateShow(this, this._children, isShowing);
  275. }
  276. this._definitionChanged.raiseEvent(this, 'parent', value, oldValue);
  277. }
  278. },
  279. /**
  280. * Gets the names of all properties registered on this instance.
  281. * @memberof Entity.prototype
  282. * @type {Array}
  283. */
  284. propertyNames : {
  285. get : function() {
  286. return this._propertyNames;
  287. }
  288. },
  289. /**
  290. * Gets or sets the billboard.
  291. * @memberof Entity.prototype
  292. * @type {BillboardGraphics}
  293. */
  294. billboard : createPropertyTypeDescriptor('billboard', BillboardGraphics),
  295. /**
  296. * Gets or sets the box.
  297. * @memberof Entity.prototype
  298. * @type {BoxGraphics}
  299. */
  300. box : createPropertyTypeDescriptor('box', BoxGraphics),
  301. /**
  302. * Gets or sets the corridor.
  303. * @memberof Entity.prototype
  304. * @type {CorridorGraphics}
  305. */
  306. corridor : createPropertyTypeDescriptor('corridor', CorridorGraphics),
  307. /**
  308. * Gets or sets the cylinder.
  309. * @memberof Entity.prototype
  310. * @type {CylinderGraphics}
  311. */
  312. cylinder : createPropertyTypeDescriptor('cylinder', CylinderGraphics),
  313. /**
  314. * Gets or sets the description.
  315. * @memberof Entity.prototype
  316. * @type {Property}
  317. */
  318. description : createPropertyDescriptor('description'),
  319. /**
  320. * Gets or sets the ellipse.
  321. * @memberof Entity.prototype
  322. * @type {EllipseGraphics}
  323. */
  324. ellipse : createPropertyTypeDescriptor('ellipse', EllipseGraphics),
  325. /**
  326. * Gets or sets the ellipsoid.
  327. * @memberof Entity.prototype
  328. * @type {EllipsoidGraphics}
  329. */
  330. ellipsoid : createPropertyTypeDescriptor('ellipsoid', EllipsoidGraphics),
  331. /**
  332. * Gets or sets the label.
  333. * @memberof Entity.prototype
  334. * @type {LabelGraphics}
  335. */
  336. label : createPropertyTypeDescriptor('label', LabelGraphics),
  337. /**
  338. * Gets or sets the model.
  339. * @memberof Entity.prototype
  340. * @type {ModelGraphics}
  341. */
  342. model : createPropertyTypeDescriptor('model', ModelGraphics),
  343. /**
  344. * Gets or sets the orientation.
  345. * @memberof Entity.prototype
  346. * @type {Property}
  347. */
  348. orientation : createPropertyDescriptor('orientation'),
  349. /**
  350. * Gets or sets the path.
  351. * @memberof Entity.prototype
  352. * @type {PathGraphics}
  353. */
  354. path : createPropertyTypeDescriptor('path', PathGraphics),
  355. /**
  356. * Gets or sets the plane.
  357. * @memberof Entity.prototype
  358. * @type {PlaneGraphics}
  359. */
  360. plane : createPropertyTypeDescriptor('plane', PlaneGraphics),
  361. /**
  362. * Gets or sets the point graphic.
  363. * @memberof Entity.prototype
  364. * @type {PointGraphics}
  365. */
  366. point : createPropertyTypeDescriptor('point', PointGraphics),
  367. /**
  368. * Gets or sets the polygon.
  369. * @memberof Entity.prototype
  370. * @type {PolygonGraphics}
  371. */
  372. polygon : createPropertyTypeDescriptor('polygon', PolygonGraphics),
  373. /**
  374. * Gets or sets the polyline.
  375. * @memberof Entity.prototype
  376. * @type {PolylineGraphics}
  377. */
  378. polyline : createPropertyTypeDescriptor('polyline', PolylineGraphics),
  379. /**
  380. * Gets or sets the polyline volume.
  381. * @memberof Entity.prototype
  382. * @type {PolylineVolumeGraphics}
  383. */
  384. polylineVolume : createPropertyTypeDescriptor('polylineVolume', PolylineVolumeGraphics),
  385. /**
  386. * Gets or sets the bag of arbitrary properties associated with this entity.
  387. * @memberof Entity.prototype
  388. * @type {PropertyBag}
  389. */
  390. properties : createPropertyTypeDescriptor('properties', PropertyBag),
  391. /**
  392. * Gets or sets the position.
  393. * @memberof Entity.prototype
  394. * @type {PositionProperty}
  395. */
  396. position : createPositionPropertyDescriptor('position'),
  397. /**
  398. * Gets or sets the rectangle.
  399. * @memberof Entity.prototype
  400. * @type {RectangleGraphics}
  401. */
  402. rectangle : createPropertyTypeDescriptor('rectangle', RectangleGraphics),
  403. /**
  404. * Gets or sets the suggested initial offset when tracking this object.
  405. * The offset is typically defined in the east-north-up reference frame,
  406. * but may be another frame depending on the object's velocity.
  407. * @memberof Entity.prototype
  408. * @type {Property}
  409. */
  410. viewFrom : createPropertyDescriptor('viewFrom'),
  411. /**
  412. * Gets or sets the wall.
  413. * @memberof Entity.prototype
  414. * @type {WallGraphics}
  415. */
  416. wall : createPropertyTypeDescriptor('wall', WallGraphics)
  417. });
  418. /**
  419. * Given a time, returns true if this object should have data during that time.
  420. *
  421. * @param {JulianDate} time The time to check availability for.
  422. * @returns {Boolean} true if the object should have data during the provided time, false otherwise.
  423. */
  424. Entity.prototype.isAvailable = function(time) {
  425. //>>includeStart('debug', pragmas.debug);
  426. if (!defined(time)) {
  427. throw new DeveloperError('time is required.');
  428. }
  429. //>>includeEnd('debug');
  430. var availability = this._availability;
  431. return !defined(availability) || availability.contains(time);
  432. };
  433. /**
  434. * Adds a property to this object. Once a property is added, it can be
  435. * observed with {@link Entity#definitionChanged} and composited
  436. * with {@link CompositeEntityCollection}
  437. *
  438. * @param {String} propertyName The name of the property to add.
  439. *
  440. * @exception {DeveloperError} "propertyName" is a reserved property name.
  441. * @exception {DeveloperError} "propertyName" is already a registered property.
  442. */
  443. Entity.prototype.addProperty = function(propertyName) {
  444. var propertyNames = this._propertyNames;
  445. //>>includeStart('debug', pragmas.debug);
  446. if (!defined(propertyName)) {
  447. throw new DeveloperError('propertyName is required.');
  448. }
  449. if (propertyNames.indexOf(propertyName) !== -1) {
  450. throw new DeveloperError(propertyName + ' is already a registered property.');
  451. }
  452. if (propertyName in this) {
  453. throw new DeveloperError(propertyName + ' is a reserved property name.');
  454. }
  455. //>>includeEnd('debug');
  456. propertyNames.push(propertyName);
  457. Object.defineProperty(this, propertyName, createRawPropertyDescriptor(propertyName, true));
  458. };
  459. /**
  460. * Removed a property previously added with addProperty.
  461. *
  462. * @param {String} propertyName The name of the property to remove.
  463. *
  464. * @exception {DeveloperError} "propertyName" is a reserved property name.
  465. * @exception {DeveloperError} "propertyName" is not a registered property.
  466. */
  467. Entity.prototype.removeProperty = function(propertyName) {
  468. var propertyNames = this._propertyNames;
  469. var index = propertyNames.indexOf(propertyName);
  470. //>>includeStart('debug', pragmas.debug);
  471. if (!defined(propertyName)) {
  472. throw new DeveloperError('propertyName is required.');
  473. }
  474. if (index === -1) {
  475. throw new DeveloperError(propertyName + ' is not a registered property.');
  476. }
  477. //>>includeEnd('debug');
  478. this._propertyNames.splice(index, 1);
  479. delete this[propertyName];
  480. };
  481. /**
  482. * Assigns each unassigned property on this object to the value
  483. * of the same property on the provided source object.
  484. *
  485. * @param {Entity} source The object to be merged into this object.
  486. */
  487. Entity.prototype.merge = function(source) {
  488. //>>includeStart('debug', pragmas.debug);
  489. if (!defined(source)) {
  490. throw new DeveloperError('source is required.');
  491. }
  492. //>>includeEnd('debug');
  493. //Name, show, and availability are not Property objects and are currently handled differently.
  494. //source.show is intentionally ignored because this.show always has a value.
  495. this.name = defaultValue(this.name, source.name);
  496. this.availability = defaultValue(this.availability, source.availability);
  497. var propertyNames = this._propertyNames;
  498. var sourcePropertyNames = defined(source._propertyNames) ? source._propertyNames : Object.keys(source);
  499. var propertyNamesLength = sourcePropertyNames.length;
  500. for (var i = 0; i < propertyNamesLength; i++) {
  501. var name = sourcePropertyNames[i];
  502. //Ignore parent when merging, this only happens at construction time.
  503. if (name === 'parent') {
  504. continue;
  505. }
  506. var targetProperty = this[name];
  507. var sourceProperty = source[name];
  508. //Custom properties that are registered on the source entity must also
  509. //get registered on this entity.
  510. if (!defined(targetProperty) && propertyNames.indexOf(name) === -1) {
  511. this.addProperty(name);
  512. }
  513. if (defined(sourceProperty)) {
  514. if (defined(targetProperty)) {
  515. if (defined(targetProperty.merge)) {
  516. targetProperty.merge(sourceProperty);
  517. }
  518. } else if (defined(sourceProperty.merge) && defined(sourceProperty.clone)) {
  519. this[name] = sourceProperty.clone();
  520. } else {
  521. this[name] = sourceProperty;
  522. }
  523. }
  524. }
  525. };
  526. var matrix3Scratch = new Matrix3();
  527. var positionScratch = new Cartesian3();
  528. var orientationScratch = new Quaternion();
  529. /**
  530. * Computes the model matrix for the entity's transform at specified time. Returns undefined if orientation or position
  531. * are undefined.
  532. *
  533. * @param {JulianDate} time The time to retrieve model matrix for.
  534. * @param {Matrix4} [result] The object onto which to store the result.
  535. *
  536. * @returns {Matrix4} The modified result parameter or a new Matrix4 instance if one was not provided. Result is undefined if position or orientation are undefined.
  537. */
  538. Entity.prototype.computeModelMatrix = function(time, result) {
  539. //>>includeStart('debug', pragmas.debug);
  540. Check.typeOf.object('time', time);
  541. //>>includeEnd('debug');
  542. var position = Property.getValueOrUndefined(this._position, time, positionScratch);
  543. if (!defined(position)) {
  544. return undefined;
  545. }
  546. var orientation = Property.getValueOrUndefined(this._orientation, time, orientationScratch);
  547. if (!defined(orientation)) {
  548. result = Transforms.eastNorthUpToFixedFrame(position, undefined, result);
  549. } else {
  550. result = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, result);
  551. }
  552. return result;
  553. };
  554. /**
  555. * @private
  556. */
  557. Entity.prototype.computeModelMatrixForHeightReference = function(time, heightReferenceProperty, heightOffset, ellipsoid, result) {
  558. //>>includeStart('debug', pragmas.debug);
  559. Check.typeOf.object('time', time);
  560. //>>includeEnd('debug');
  561. var heightReference = Property.getValueOrDefault(heightReferenceProperty, time, HeightReference.NONE);
  562. var position = Property.getValueOrUndefined(this._position, time, positionScratch);
  563. if (heightReference === HeightReference.NONE || !defined(position) || Cartesian3.equalsEpsilon(position, Cartesian3.ZERO, CesiumMath.EPSILON8)) {
  564. return this.computeModelMatrix(time, result);
  565. }
  566. var carto = ellipsoid.cartesianToCartographic(position, cartoScratch);
  567. if (heightReference === HeightReference.CLAMP_TO_GROUND) {
  568. carto.height = heightOffset;
  569. } else {
  570. carto.height += heightOffset;
  571. }
  572. position = ellipsoid.cartographicToCartesian(carto, position);
  573. var orientation = Property.getValueOrUndefined(this._orientation, time, orientationScratch);
  574. if (!defined(orientation)) {
  575. result = Transforms.eastNorthUpToFixedFrame(position, undefined, result);
  576. } else {
  577. result = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, result);
  578. }
  579. return result;
  580. };
  581. /**
  582. * Checks if the given Scene supports materials besides Color on Entities draped on terrain or 3D Tiles.
  583. * If this feature is not supported, Entities with non-color materials but no `height` will
  584. * instead be rendered as if height is 0.
  585. *
  586. * @param {Scene} scene The current scene.
  587. * @returns {Boolean} Whether or not the current scene supports materials for entities on terrain.
  588. */
  589. Entity.supportsMaterialsforEntitiesOnTerrain = function(scene) {
  590. return GroundPrimitive.supportsMaterials(scene);
  591. };
  592. /**
  593. * Checks if the given Scene supports polylines clamped to terrain or 3D Tiles.
  594. * If this feature is not supported, Entities with PolylineGraphics will be rendered with vertices at
  595. * the provided heights and using the `arcType` parameter instead of clamped to the ground.
  596. *
  597. * @param {Scene} scene The current scene.
  598. * @returns {Boolean} Whether or not the current scene supports polylines on terrain or 3D TIles.
  599. */
  600. Entity.supportsPolylinesOnTerrain = function(scene) {
  601. return GroundPolylinePrimitive.isSupported(scene);
  602. };
  603. export default Entity;