Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

DiffuseWallPrimitive.js 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /**
  2. * @Author: Caven
  3. * @Date: 2021-06-04 20:38:39
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import State from '@dc-modules/state/State'
  7. import Parse from '@dc-modules/parse/Parse'
  8. import { Util } from '@dc-modules/utils'
  9. import { Transform } from '@dc-modules/transform'
  10. import Overlay from '../Overlay'
  11. const DEF_STYLE = {
  12. minRadius: 10,
  13. minHeight: 30,
  14. color: Cesium.Color.RED,
  15. slices: 128,
  16. speed: 10
  17. }
  18. class DiffuseWallPrimitive extends Overlay {
  19. constructor(center, radius, height) {
  20. super()
  21. this._center = Parse.parsePosition(center)
  22. this._delegate = undefined
  23. this._height = height
  24. this._radius = radius
  25. this._currentHeight = height || 0
  26. this._currentRadius = 10
  27. this._style = { ...DEF_STYLE }
  28. this._state = State.INITIALIZED
  29. }
  30. get type() {
  31. return Overlay.getOverlayType('diffuse_wall_primitive')
  32. }
  33. set center(position) {
  34. this._center = Parse.parsePosition(position)
  35. return this
  36. }
  37. get center() {
  38. return this._center
  39. }
  40. set radius(radius) {
  41. this._radius = radius
  42. return this
  43. }
  44. get radius() {
  45. return this._radius
  46. }
  47. set height(height) {
  48. this._height = height
  49. return this
  50. }
  51. get height() {
  52. return this._height
  53. }
  54. /**
  55. *
  56. * @returns {*}
  57. * @private
  58. */
  59. _getPositions() {
  60. let pnts = []
  61. let modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
  62. Transform.transformWGS84ToCartesian(this._center)
  63. )
  64. for (let i = 0; i < this._style.slices; i++) {
  65. let angle = (i / this._style.slices) * Cesium.Math.TWO_PI
  66. let x = Math.cos(angle)
  67. let y = Math.sin(angle)
  68. let point = new Cesium.Cartesian3(
  69. x * this._currentRadius,
  70. y * this._currentRadius,
  71. 0.0
  72. )
  73. pnts.push(
  74. Cesium.Matrix4.multiplyByPoint(
  75. modelMatrix,
  76. point,
  77. new Cesium.Cartesian3()
  78. )
  79. )
  80. }
  81. pnts.push(pnts[0])
  82. return pnts
  83. }
  84. /**
  85. *
  86. * @param length
  87. * @param hegiht
  88. * @returns {*[]}
  89. * @private
  90. */
  91. _getHeights(length, hegiht) {
  92. let heights = []
  93. for (let i = 0; i < length; i++) {
  94. heights.push(hegiht)
  95. }
  96. return heights
  97. }
  98. /**
  99. *
  100. * @param layer
  101. * @private
  102. */
  103. _onAdd(layer) {
  104. if (!layer) {
  105. return
  106. }
  107. this._layer = layer
  108. if (this._layer?.delegate?.add) {
  109. this._layer.delegate.add(this)
  110. }
  111. this._addedHook && this._addedHook()
  112. this._state = State.ADDED
  113. }
  114. /**
  115. *
  116. * @private
  117. */
  118. _onRemove() {
  119. if (!this._layer) {
  120. return
  121. }
  122. if (this._layer?.delegate?.remove) {
  123. this._layer.delegate.remove(this)
  124. }
  125. this._state = State.REMOVED
  126. }
  127. /**
  128. *
  129. * @param frameState
  130. * @returns {boolean}
  131. */
  132. update(frameState) {
  133. this._delegate = this._delegate && this._delegate.destroy()
  134. this._currentRadius += this._radius / this._style.speed / 20
  135. this._currentHeight -= this._height / this._style.speed / 20
  136. if (
  137. this._currentRadius > this._radius ||
  138. this._currentHeight < this._style.minHeight
  139. ) {
  140. this._currentRadius = this._style.minRadius
  141. this._currentHeight = this._height
  142. }
  143. if (!this._style.slices || this._style.slices < 3) {
  144. return false
  145. }
  146. let positions = this._getPositions()
  147. if (!positions || !positions.length) {
  148. return false
  149. }
  150. let geometry = new Cesium.WallGeometry({
  151. positions: positions,
  152. minimumHeights: this._getHeights(positions.length, 0),
  153. maximumHeights: this._getHeights(positions.length, this._currentHeight)
  154. })
  155. this._delegate = new Cesium.Primitive({
  156. geometryInstances: new Cesium.GeometryInstance({
  157. geometry
  158. }),
  159. appearance: new Cesium.MaterialAppearance({
  160. material: Cesium.Material.fromType('WallDiffuse', {
  161. color: this._style?.color
  162. }),
  163. flat: true
  164. }),
  165. asynchronous: false
  166. })
  167. this._delegate.update(frameState)
  168. }
  169. /**
  170. *
  171. * @param style
  172. * @returns {DiffuseWallPrimitive}
  173. */
  174. setStyle(style) {
  175. if (!style || Object.keys(style).length === 0) {
  176. return this
  177. }
  178. Util.merge(this._style, style)
  179. return this
  180. }
  181. }
  182. Overlay.registerType('diffuse_wall_primitive')
  183. export default DiffuseWallPrimitive