You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RenderEntity.js 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import S3MCreateVertexJob from '../S3MCreateVertexJob.js'
  2. import S3MCreateIndexJob from '../S3MCreateIndexJob.js'
  3. import S3MCreateShaderProgramJob from '../S3MCreateShaderProgramJob.js'
  4. import MaterialPass from '../MaterialPass.js'
  5. const { Cesium } = DC.Namespace
  6. function RenderEntity(options) {
  7. this.layer = options.layer
  8. this.vertexPackage = options.vertexPackage
  9. this.arrIndexPackage = options.arrIndexPackage
  10. this.vertexBufferToCreate = new Cesium.Queue()
  11. this.indexBufferToCreate = new Cesium.Queue()
  12. this.shaderProgramToCreate = new Cesium.Queue()
  13. let i, j
  14. for (i = 0, j = this.vertexPackage.vertexAttributes.length; i < j; i++) {
  15. this.vertexBufferToCreate.enqueue(i)
  16. }
  17. for (i = 0, j = this.arrIndexPackage.length; i < j; i++) {
  18. this.indexBufferToCreate.enqueue(i)
  19. }
  20. this.shaderProgramToCreate.enqueue(0)
  21. this.boundingVolume = options.boundingVolume
  22. this.material = Cesium.defaultValue(options.material, new MaterialPass())
  23. this.geoName = options.geoName
  24. this.modelMatrix = options.modelMatrix
  25. this.geoMatrix = options.geoMatrix
  26. this.invGeoMatrix = Cesium.Matrix4.inverse(
  27. this.geoMatrix,
  28. new Cesium.Matrix4()
  29. )
  30. this.instanceCount = options.vertexPackage.instanceCount
  31. this.attributeLocations = options.vertexPackage.attrLocation
  32. this.shaderProgram = undefined
  33. this.vertexArray = undefined
  34. this.colorCommand = undefined
  35. this.pickInfo = Cesium.defaultValue(options.pickInfo, {})
  36. this.selectionInfoMap = new Cesium.AssociativeArray()
  37. this.batchTable = undefined
  38. this.batchTableDirty = false
  39. this.idsOperationMap = new Cesium.AssociativeArray()
  40. this.pickColorIdentifier = 'vSecondColor'
  41. this.createBoundingBoxForInstance()
  42. this.ready = false
  43. }
  44. const _vertexBufferJob = new S3MCreateVertexJob()
  45. const _indexBufferJob = new S3MCreateIndexJob()
  46. const _shaderProgramJob = new S3MCreateShaderProgramJob()
  47. function createVertexBuffers(renderEntity, frameState) {
  48. let context = renderEntity.layer.context
  49. let queue = renderEntity.vertexBufferToCreate
  50. while (queue.length) {
  51. let index = queue.peek()
  52. _vertexBufferJob.set(context, renderEntity, index)
  53. if (
  54. !frameState.jobScheduler.execute(_vertexBufferJob, Cesium.JobType.BUFFER)
  55. ) {
  56. break
  57. }
  58. queue.dequeue()
  59. }
  60. }
  61. function createIndexBuffers(renderEntity, frameState) {
  62. let context = renderEntity.layer.context
  63. let queue = renderEntity.indexBufferToCreate
  64. while (queue.length) {
  65. let index = queue.peek()
  66. _indexBufferJob.set(context, renderEntity, index)
  67. if (
  68. !frameState.jobScheduler.execute(_indexBufferJob, Cesium.JobType.BUFFER)
  69. ) {
  70. break
  71. }
  72. queue.dequeue()
  73. }
  74. }
  75. function createShaderProgram(renderEntity, frameState) {
  76. let context = renderEntity.layer.context
  77. let queue = renderEntity.shaderProgramToCreate
  78. while (queue.length) {
  79. let index = queue.peek()
  80. _shaderProgramJob.set(context, renderEntity)
  81. if (
  82. !frameState.jobScheduler.execute(
  83. _shaderProgramJob,
  84. Cesium.JobType.PROGRAM
  85. )
  86. ) {
  87. break
  88. }
  89. queue.dequeue()
  90. }
  91. }
  92. function createBatchTable(renderEntity, frameState) {
  93. if (Cesium.defined(renderEntity.batchTable) || !renderEntity.pickInfo) {
  94. return
  95. }
  96. const context = renderEntity.layer.context
  97. let attributes = []
  98. attributes.push(
  99. {
  100. functionName: 'batchTable_operation',
  101. componentDatatype: Cesium.ComponentDatatype.UNSIGNED_BYTE,
  102. componentsPerAttribute: 4
  103. },
  104. {
  105. functionName: 'batchTable_pickColor',
  106. componentDatatype: Cesium.ComponentDatatype.UNSIGNED_BYTE,
  107. componentsPerAttribute: 4,
  108. normalize: true
  109. }
  110. )
  111. let pickInfo = renderEntity.pickInfo
  112. let pickIds = Object.keys(pickInfo)
  113. let numberOfInstances =
  114. renderEntity.instanceCount > 0 ? renderEntity.instanceCount : pickIds.length
  115. renderEntity.batchTable = new Cesium.BatchTable(
  116. context,
  117. attributes,
  118. numberOfInstances
  119. )
  120. }
  121. RenderEntity.prototype.createBuffers = function(frameState) {
  122. createVertexBuffers(this, frameState)
  123. createIndexBuffers(this, frameState)
  124. }
  125. RenderEntity.prototype.createShaderProgram = function(frameState) {
  126. createShaderProgram(this, frameState)
  127. }
  128. RenderEntity.prototype.createBatchTable = function(frameState) {
  129. createBatchTable(this, frameState)
  130. }
  131. let scratchPntCenter = new Cesium.Cartesian3()
  132. RenderEntity.prototype.createBoundingBoxForInstance = function() {
  133. const vertexPackage = this.vertexPackage
  134. if (
  135. !Cesium.defined(vertexPackage) ||
  136. vertexPackage.instanceIndex === -1 ||
  137. !Cesium.defined(vertexPackage.instanceBounds)
  138. ) {
  139. return
  140. }
  141. let instanceBounds = vertexPackage.instanceBounds
  142. let pntLU = new Cesium.Cartesian3(
  143. instanceBounds[0],
  144. instanceBounds[1],
  145. instanceBounds[2]
  146. )
  147. let pntRD = new Cesium.Cartesian3(
  148. instanceBounds[3],
  149. instanceBounds[4],
  150. instanceBounds[5]
  151. )
  152. let pntCenter = Cesium.Cartesian3.lerp(pntLU, pntRD, 0.5, scratchPntCenter)
  153. let dRadius = Cesium.Cartesian3.distance(pntCenter, pntLU)
  154. let vecCenter = new Cesium.Cartesian3()
  155. Cesium.Matrix4.multiplyByPoint(this.modelMatrix, pntCenter, vecCenter)
  156. this.boundingVolume.center = vecCenter
  157. this.boundingVolume.radius = dRadius
  158. vertexPackage.instanceBounds = undefined
  159. }
  160. RenderEntity.prototype.initLayerSetting = function(layer) {
  161. if (Object.keys(layer._objsOperationList).length > 0) {
  162. this.updateObjsOperation(layer._objsOperationList)
  163. }
  164. }
  165. let cartesian4Scratch = new Cesium.Cartesian4()
  166. RenderEntity.prototype.createPickIds = function() {
  167. const layer = this.layer
  168. const context = layer.context
  169. const pickInfo = this.pickInfo
  170. if (!Cesium.defined(pickInfo)) {
  171. return
  172. }
  173. for (let id in pickInfo) {
  174. if (!pickInfo.hasOwnProperty(id)) {
  175. continue
  176. }
  177. this.selectionInfoMap.set(id, pickInfo[id])
  178. }
  179. let batchTable = this.batchTable
  180. let selectionInfoMap = this.selectionInfoMap
  181. let hash = selectionInfoMap._hash
  182. for (let id in hash) {
  183. if (hash.hasOwnProperty(id)) {
  184. let selInfo = selectionInfoMap.get(id)
  185. let pickId
  186. if (!Cesium.defined(pickId)) {
  187. pickId = context.createPickId({
  188. primitive: layer,
  189. id: id
  190. })
  191. }
  192. let pickColor = pickId.color
  193. cartesian4Scratch.x = Cesium.Color.floatToByte(pickColor.red)
  194. cartesian4Scratch.y = Cesium.Color.floatToByte(pickColor.green)
  195. cartesian4Scratch.z = Cesium.Color.floatToByte(pickColor.blue)
  196. cartesian4Scratch.w = Cesium.Color.floatToByte(pickColor.alpha)
  197. let instanceIds = selInfo.instanceIds
  198. if (this.instanceCount > 0) {
  199. instanceIds.map(function(instanceId) {
  200. batchTable.setBatchedAttribute(instanceId, 1, cartesian4Scratch)
  201. })
  202. } else {
  203. let batchId = selInfo[0].batchId
  204. batchTable.setBatchedAttribute(batchId, 1, cartesian4Scratch)
  205. }
  206. }
  207. }
  208. this.pickInfo = undefined
  209. }
  210. RenderEntity.prototype.updateBatchTableAttributes = function() {
  211. let ro = this
  212. let idsOperationMap = this.idsOperationMap
  213. for (let i = 0, j = idsOperationMap.length; i < j; i++) {
  214. let obj = idsOperationMap.values[i]
  215. if (!obj.dirty) {
  216. continue
  217. }
  218. obj.dirty = false
  219. if (this.instanceCount > 0) {
  220. if (Array.isArray(obj.instanceIds)) {
  221. obj.instanceIds.map(function(instanceId) {
  222. ro.batchTable.setBatchedAttribute(instanceId, 0, obj.operationValue)
  223. })
  224. }
  225. } else {
  226. if (Cesium.defined(obj.batchId)) {
  227. this.batchTable.setBatchedAttribute(obj.batchId, 0, obj.operationValue)
  228. }
  229. }
  230. }
  231. }
  232. RenderEntity.prototype.updateObjsOperation = function(ids) {
  233. if (!this.ready || this.selectionInfoMap.length < 1) {
  234. return
  235. }
  236. let selectValues = this.selectionInfoMap._hash
  237. for (let id in selectValues) {
  238. if (!selectValues.hasOwnProperty(id)) {
  239. continue
  240. }
  241. let operationType = ids[id]
  242. if (!Cesium.defined(operationType)) {
  243. continue
  244. }
  245. let selectInfo = selectValues[id][0]
  246. let batchId = selectInfo.batchId
  247. let instanceIds = selectInfo.instanceIds
  248. let obj = this.idsOperationMap.get(id)
  249. if (!Cesium.defined(obj)) {
  250. obj = {
  251. batchId: batchId,
  252. instanceIds: instanceIds,
  253. operationValue: new Cesium.Cartesian4(),
  254. dirty: true
  255. }
  256. }
  257. obj.dirty = true
  258. obj.operationValue.x = (obj.operationValue.x & 0x01) | operationType
  259. this.idsOperationMap.set(id, obj)
  260. this.batchTableDirty = true
  261. }
  262. }
  263. RenderEntity.prototype.createCommand =
  264. Cesium.DeveloperError.throwInstantiationError
  265. RenderEntity.prototype.update = Cesium.DeveloperError.throwInstantiationError
  266. RenderEntity.prototype.isDestroyed =
  267. Cesium.DeveloperError.throwInstantiationError
  268. RenderEntity.prototype.destroy = Cesium.DeveloperError.throwInstantiationError
  269. export default RenderEntity